fix: move test helpers from samples into core (#5969)

* fix: move core test helpers into new directory

* fix: add test helpers to core and convert to goog modules

* fix: change tests to use local helpers

* fix: change local tests to use chai asserts

* fix: skip field tests in serializer b/c test blocks are unavailable

* fix: rename some helper files

* fix: rename some helper modules

* fix: split block helpers into code gen and serialization

* fix: split block defs into new helper file

* fix: split warning helpers into new file

* fix: split user input helpers into new file

* fix: split event helpers into a new file

* fix: split variable helper into new file

* fix: move remaining test helpers to new setup-teardown file

* fix: rename setup and teardown module

* fix: cleanup from rebase

* fix: undo accidental rename

* fix: lint?

* fix: bad toolbox definitions namespace

* fix: fixup warning helpers

* fix: remove inclusion of dev-tools in mocha tests

* move to modules, but break mocha

* fix: run mocha as a module

* fix: lint
This commit is contained in:
Beka Westberg
2022-03-04 13:10:03 -08:00
committed by GitHub
parent 6841ccc99f
commit 2edd228117
74 changed files with 1713 additions and 985 deletions
+70 -61
View File
@@ -1,64 +1,73 @@
goog.addDependency('../../tests/mocha/.mocharc.js', [], []);
goog.addDependency('../../tests/mocha/astnode_test.js', ['Blockly.test.astNode'], ['Blockly.ASTNode', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_change_event_test.js', ['Blockly.test.blockChangeEvent'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_create_event_test.js', ['Blockly.test.blockCreateEvent'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/astnode_test.js', ['Blockly.test.astNode'], ['Blockly.ASTNode', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_change_event_test.js', ['Blockly.test.blockChangeEvent'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_create_event_test.js', ['Blockly.test.blockCreateEvent'], ['Blockly.Events.utils', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_json_test.js', ['Blockly.test.blockJson'], ['Blockly.Input'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_test.js', ['Blockly.test.blocks'], ['Blockly.ConnectionType', 'Blockly.Events.utils', 'Blockly.blocks', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/comment_test.js', ['Blockly.test.comments'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/connection_checker_test.js', ['Blockly.test.connectionChecker'], ['Blockly.ConnectionType', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/connection_db_test.js', ['Blockly.test.connectionDb'], ['Blockly.ConnectionType', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/connection_test.js', ['Blockly.test.connection'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/contextmenu_items_test.js', ['Blockly.test.contextMenuItem'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/cursor_test.js', ['Blockly.test.cursor'], ['Blockly.ASTNode', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/dropdowndiv_test.js', ['Blockly.test.dropdown'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/event_test.js', ['Blockly.test.event'], ['Blockly.ASTNode', 'Blockly.Events.utils', 'Blockly.WorkspaceComment', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/extensions_test.js', ['Blockly.test.extensions'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_angle_test.js', ['Blockly.test.fieldAngle'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_checkbox_test.js', ['Blockly.test.fieldCheckbox'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_colour_test.js', ['Blockly.test.fieldColour'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_dropdown_test.js', ['Blockly.test.fieldDropdown'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_image_test.js', ['Blockly.test.fieldImage'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_label_serializable_test.js', ['Blockly.test.fieldLabelSerialization'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_label_test.js', ['Blockly.test.fieldLabel'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_multilineinput_test.js', ['Blockly.test.fieldMultiline'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_number_test.js', ['Blockly.test.fieldNumber'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_registry_test.js', ['Blockly.test.fieldRegistry'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_test.js', ['Blockly.test.fieldTest'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_textinput_test.js', ['Blockly.test.fieldTextInput'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_variable_test.js', ['Blockly.test.fieldVariable'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/flyout_test.js', ['Blockly.test.flyout'], ['Blockly.test.helpers', 'Blockly.test.toolboxHelpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/generator_test.js', ['Blockly.test.generator'], ['Blockly.Dart', 'Blockly.JavaScript', 'Blockly.Lua', 'Blockly.PHP', 'Blockly.Python', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/gesture_test.js', ['Blockly.test.gesture'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/input_test.js', ['Blockly.test.input'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/insertion_marker_test.js', ['Blockly.test.insertionMarker'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/jso_deserialization_test.js', ['Blockly.test.jsoDeserialization'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/jso_serialization_test.js', ['Blockly.test.jsoSerialization'], ['Blockly.test.helpers'], {'lang': 'es8', 'module': 'goog'});
goog.addDependency('../../tests/mocha/json_test.js', ['Blockly.test.json'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/keydown_test.js', ['Blockly.test.keydown'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/logic_ternary_test.js', ['Blockly.test.logicTernary'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/metrics_test.js', ['Blockly.test.metrics'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/mutator_test.js', ['Blockly.test.mutator'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/names_test.js', ['Blockly.test.names'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/procedures_test.js', ['Blockly.test.procedures'], ['Blockly', 'Blockly.Msg', 'Blockly.test.helpers', 'Blockly.test.procedureHelpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/procedures_test_helpers.js', ['Blockly.test.procedureHelpers'], ['Blockly.ConnectionType'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/registry_test.js', ['Blockly.test.registry'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/block_test.js', ['Blockly.test.blocks'], ['Blockly.ConnectionType', 'Blockly.Events.utils', 'Blockly.blocks', 'Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.warnings'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/comment_test.js', ['Blockly.test.comments'], ['Blockly.Events.utils', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/connection_checker_test.js', ['Blockly.test.connectionChecker'], ['Blockly.ConnectionType', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/connection_db_test.js', ['Blockly.test.connectionDb'], ['Blockly.ConnectionType', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/connection_test.js', ['Blockly.test.connection'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/contextmenu_items_test.js', ['Blockly.test.contextMenuItem'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/cursor_test.js', ['Blockly.test.cursor'], ['Blockly.ASTNode', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/dropdowndiv_test.js', ['Blockly.test.dropdown'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/event_test.js', ['Blockly.test.event'], ['Blockly.ASTNode', 'Blockly.Events.utils', 'Blockly.WorkspaceComment', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.variables'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/extensions_test.js', ['Blockly.test.extensions'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_angle_test.js', ['Blockly.test.fieldAngle'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_checkbox_test.js', ['Blockly.test.fieldCheckbox'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_colour_test.js', ['Blockly.test.fieldColour'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_dropdown_test.js', ['Blockly.test.fieldDropdown'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_image_test.js', ['Blockly.test.fieldImage'], ['Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_label_serializable_test.js', ['Blockly.test.fieldLabelSerialization'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_label_test.js', ['Blockly.test.fieldLabel'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_multilineinput_test.js', ['Blockly.test.fieldMultiline'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.codeGeneration', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_number_test.js', ['Blockly.test.fieldNumber'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.common', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_registry_test.js', ['Blockly.test.fieldRegistry'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.warnings'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_test.js', ['Blockly.test.fieldTest'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.warnings'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_textinput_test.js', ['Blockly.test.fieldTextInput'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/field_variable_test.js', ['Blockly.test.fieldVariable'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.fields', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/flyout_test.js', ['Blockly.test.flyout'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.toolboxDefinitions'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/generator_test.js', ['Blockly.test.generator'], ['Blockly.Dart', 'Blockly.JavaScript', 'Blockly.Lua', 'Blockly.PHP', 'Blockly.Python', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/gesture_test.js', ['Blockly.test.gesture'], ['Blockly.Events.utils', 'Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.userInput'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/input_test.js', ['Blockly.test.input'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/insertion_marker_test.js', ['Blockly.test.insertionMarker'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/jso_deserialization_test.js', ['Blockly.test.jsoDeserialization'], ['Blockly.Events.utils', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/jso_serialization_test.js', ['Blockly.test.jsoSerialization'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es8', 'module': 'goog'});
goog.addDependency('../../tests/mocha/json_test.js', ['Blockly.test.json'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.warnings'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/keydown_test.js', ['Blockly.test.keydown'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.userInput'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/logic_ternary_test.js', ['Blockly.test.logicTernary'], ['Blockly.Events.utils', 'Blockly.test.helpers.serialization', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/metrics_test.js', ['Blockly.test.metrics'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/mutator_test.js', ['Blockly.test.mutator'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/names_test.js', ['Blockly.test.names'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/procedures_test.js', ['Blockly.test.procedures'], ['Blockly', 'Blockly.Msg', 'Blockly.test.helpers.procedures', 'Blockly.test.helpers.serialization', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/registry_test.js', ['Blockly.test.registry'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.warnings'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/run_mocha_tests_in_browser.js', [], [], {'lang': 'es8'});
goog.addDependency('../../tests/mocha/serializer_test.js', ['Blockly.test.serialization'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/shortcut_registry_test.js', ['Blockly.test.shortcutRegistry'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/test_helpers.js', ['Blockly.test.helpers'], ['Blockly.Events.utils', 'Blockly.blocks', 'Blockly.utils.KeyCodes'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/theme_test.js', ['Blockly.test.theme'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/toolbox_helper.js', ['Blockly.test.toolboxHelpers'], [], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/toolbox_test.js', ['Blockly.test.toolbox'], ['Blockly.test.helpers', 'Blockly.test.toolboxHelpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/tooltip_test.js', ['Blockly.test.tooltip'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/trashcan_test.js', ['Blockly.test.trashcan'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/utils_test.js', ['Blockly.test.utils'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/variable_map_test.js', ['Blockly.test.variableMap'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/variable_model_test.js', ['Blockly.test.variableModel'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/variables_test.js', ['Blockly.test.variables'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/widget_div_test.js', ['Blockly.test.widgetDiv'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_comment_test.js', ['Blockly.test.workspaceComment'], ['Blockly.WorkspaceComment', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_helpers.js', ['Blockly.test.workspaceHelpers'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_svg_test.js', ['Blockly.test.workspaceSvg'], ['Blockly.Events.utils', 'Blockly.test.helpers', 'Blockly.test.workspaceHelpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_test.js', ['Blockly.test.workspace'], ['Blockly.test.helpers', 'Blockly.test.workspaceHelpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/xml_test.js', ['Blockly.test.xml'], ['Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/zoom_controls_test.js', ['Blockly.test.zoomControls'], ['Blockly.Events.utils', 'Blockly.test.helpers'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/serializer_test.js', ['Blockly.test.serialization'], ['Blockly.test.helpers.common', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/shortcut_registry_test.js', ['Blockly.test.shortcutRegistry'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.userInput'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/test_helpers/block_definitions.js', ['Blockly.test.helpers.blockDefinitions'], [], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/code_generation.js', ['Blockly.test.helpers.codeGeneration'], ['Blockly.test.helpers.common'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/common.js', ['Blockly.test.helpers.common'], [], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/events.js', ['Blockly.test.helpers.events'], [], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/fields.js', ['Blockly.test.helpers.fields'], ['Blockly.test.helpers.common'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/procedures.js', ['Blockly.test.helpers.procedures'], ['Blockly.ConnectionType'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/serialization.js', ['Blockly.test.helpers.serialization'], ['Blockly.test.helpers.common'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/setup_teardown.js', ['Blockly.test.helpers.setupTeardown'], ['Blockly.Events.utils', 'Blockly.blocks'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/toolbox_definitions.js', ['Blockly.test.helpers.toolboxDefinitions'], [], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/user_input.js', ['Blockly.test.helpers.userInput'], ['Blockly.utils.KeyCodes'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/variables.js', ['Blockly.test.helpers.variables'], [], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/warnings.js', ['Blockly.test.helpers.warnings'], [], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/test_helpers/workspace.js', ['Blockly.test.helpers.workspace'], ['Blockly.Events.utils', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.variables', 'Blockly.test.helpers.warnings'], {'lang': 'es6', 'module': 'es6'});
goog.addDependency('../../tests/mocha/theme_test.js', ['Blockly.test.theme'], ['Blockly.Events.utils', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/toolbox_test.js', ['Blockly.test.toolbox'], ['Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.toolboxDefinitions'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/tooltip_test.js', ['Blockly.test.tooltip'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/trashcan_test.js', ['Blockly.test.trashcan'], ['Blockly.Events.utils', 'Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.userInput'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/utils_test.js', ['Blockly.test.utils'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/variable_map_test.js', ['Blockly.test.variableMap'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.variables'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/variable_model_test.js', ['Blockly.test.variableModel'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/variables_test.js', ['Blockly.test.variables'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/widget_div_test.js', ['Blockly.test.widgetDiv'], ['Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_comment_test.js', ['Blockly.test.workspaceComment'], ['Blockly.WorkspaceComment', 'Blockly.test.helpers.setupTeardown'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_svg_test.js', ['Blockly.test.workspaceSvg'], ['Blockly.Events.utils', 'Blockly.test.helpers.blockDefinitions', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.variables', 'Blockly.test.helpers.workspace'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/workspace_test.js', ['Blockly.test.workspace'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.variables', 'Blockly.test.helpers.workspace'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/xml_test.js', ['Blockly.test.xml'], ['Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.variables'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../tests/mocha/zoom_controls_test.js', ['Blockly.test.zoomControls'], ['Blockly.Events.utils', 'Blockly.test.helpers.events', 'Blockly.test.helpers.setupTeardown', 'Blockly.test.helpers.userInput'], {'lang': 'es6', 'module': 'goog'});
+6 -3
View File
@@ -1,18 +1,21 @@
{
"parserOptions": {
"sourceType": "module"
},
"env": {
"browser": true,
"mocha": true
},
"globals": {
"chai": false,
"sinon": false,
"testHelpers": true
"sinon": false
},
"rules": {
"no-unused-vars": ["off"],
// Allow uncommented helper functions in tests.
"require-jsdoc": ["off"],
"prefer-rest-params": ["off"]
"prefer-rest-params": ["off"],
"no-invalid-this": ["off"]
},
"extends": "../../.eslintrc.json"
}
+7 -1
View File
@@ -7,10 +7,11 @@
goog.module('Blockly.test.astNode');
const {ASTNode} = goog.require('Blockly.ASTNode');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('ASTNode', function() {
console.log('1/a');
setup(function() {
sharedTestSetup.call(this);
Blockly.defineBlocksWithJsonArray([{
@@ -100,7 +101,9 @@ suite('ASTNode', function() {
});
suite('HelperFunctions', function() {
console.log('2');
test('findNextForInput_', function() {
console.log('3');
const input = this.blocks.statementInput1.inputList[0];
const input2 = this.blocks.statementInput1.inputList[1];
const connection = input.connection;
@@ -169,6 +172,7 @@ suite('ASTNode', function() {
});
suite('NavigationFunctions', function() {
console.log('b');
setup(function() {
Blockly.defineBlocksWithJsonArray([{
"type": "top_connection",
@@ -319,7 +323,9 @@ suite('ASTNode', function() {
workspaceTeardown.call(this, this.singleBlockWorkspace);
});
console.log('c');
test('fromPreviousToBlock', function() {
console.log('d');
const prevConnection = this.blocks.statementInput1.previousConnection;
const node = ASTNode.createConnectionNode(prevConnection);
const nextNode = node.next();
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.blockChangeEvent');
const {defineMutatorBlocks, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {defineMutatorBlocks} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Block Change Event', function() {
+2 -1
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.blockCreateEvent');
const {assertEventFired} = goog.require('Blockly.test.helpers.events');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Block Create Event', function() {
+4 -2
View File
@@ -6,10 +6,12 @@
goog.module('Blockly.test.blocks');
const eventUtils = goog.require('Blockly.Events.utils');
const {Blocks} = goog.require('Blockly.blocks');
const {ConnectionType} = goog.require('Blockly.ConnectionType');
const {createDeprecationWarningStub, createRenderedBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {createDeprecationWarningStub} = goog.require('Blockly.test.helpers.warnings');
const {createRenderedBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const eventUtils = goog.require('Blockly.Events.utils');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Blocks', function() {
+2 -1
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.comments');
const {assertEventFired} = goog.require('Blockly.test.helpers.events');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Comments', function() {
+1 -1
View File
@@ -7,7 +7,7 @@
goog.module('Blockly.test.connectionChecker');
const {ConnectionType} = goog.require('Blockly.ConnectionType');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Connection checker', function() {
+1 -1
View File
@@ -7,7 +7,7 @@
goog.module('Blockly.test.connectionDb');
const {ConnectionType} = goog.require('Blockly.ConnectionType');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Connection Database', function() {
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.connection');
const {assertSingleDeprecationWarningCall, createDeprecationWarningStub, createGenUidStubWithReturns, defineRowBlock, defineStatementBlock, defineStackBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {defineRowBlock, defineStatementBlock, defineStackBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Connection', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.contextMenuItem');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Context Menu Items', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.cursor');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {ASTNode} = goog.require('Blockly.ASTNode');
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.dropdown');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('DropDownDiv', function() {
+4 -2
View File
@@ -6,9 +6,11 @@
goog.module('Blockly.test.event');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventEquals, assertNthCallEventArgEquals, assertVariableValues, createFireChangeListenerSpy, createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {ASTNode} = goog.require('Blockly.ASTNode');
const {assertEventEquals, assertNthCallEventArgEquals, createFireChangeListenerSpy} = goog.require('Blockly.test.helpers.events');
const {assertVariableValues} = goog.require('Blockly.test.helpers.variables');
const {createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const eventUtils = goog.require('Blockly.Events.utils');
goog.require('Blockly.WorkspaceComment');
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.extensions');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Extensions', function() {
+13 -11
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldAngle');
const {createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Angle Fields', function() {
@@ -60,7 +62,7 @@ suite('Angle Fields', function() {
* @param {FieldTemplate} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, defaultFieldValue);
assertFieldValue(field, defaultFieldValue);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -68,14 +70,14 @@ suite('Angle Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue);
assertFieldValue(field, testCase.expectedValue);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldAngle, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldAngle, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -84,12 +86,12 @@ suite('Angle Fields', function() {
setup(function() {
this.field = new Blockly.FieldAngle();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue(2.5);
testHelpers.assertFieldValue(this.field, 2.5);
assertFieldValue(this.field, 2.5);
});
});
suite('Value -> New Value', function() {
@@ -97,12 +99,12 @@ suite('Angle Fields', function() {
setup(function() {
this.field = new Blockly.FieldAngle(initialValue);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, initialValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue(2.5);
testHelpers.assertFieldValue(this.field, 2.5);
assertFieldValue(this.field, 2.5);
});
});
});
@@ -142,12 +144,12 @@ suite('Angle Fields', function() {
this.field.isBeingEdited_ = true;
this.field.htmlInput_.value = String(suiteInfo.value);
this.field.onHtmlInputChange_(null);
testHelpers.assertFieldValue(
assertFieldValue(
this.field, suiteInfo.expectedValue, String(suiteInfo.value));
});
test('When Not Editing', function() {
this.field.setValue(suiteInfo.value);
testHelpers.assertFieldValue(this.field, suiteInfo.expectedValue);
assertFieldValue(this.field, suiteInfo.expectedValue);
});
});
});
+10 -8
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldCheckbox');
const {defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Checkbox Fields', function() {
@@ -61,7 +63,7 @@ suite('Checkbox Fields', function() {
* @param {!Blockly.FieldCheckbox} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(
assertFieldValue(
field, defaultFieldValue, defaultFieldValue.toLowerCase());
};
/**
@@ -70,15 +72,15 @@ suite('Checkbox Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(
assertFieldValue(
field, testCase.expectedValue, testCase.expectedValue.toLowerCase());
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldCheckbox, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldCheckbox, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -87,14 +89,14 @@ suite('Checkbox Fields', function() {
setup(function() {
this.field = new Blockly.FieldCheckbox('TRUE');
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, 'TRUE', 'true');
});
suite('False -> New Value', function() {
setup(function() {
this.field = new Blockly.FieldCheckbox('FALSE');
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, 'FALSE', 'false');
});
});
@@ -131,7 +133,7 @@ suite('Checkbox Fields', function() {
});
test('New Value', function() {
this.field.setValue(suiteInfo.value);
testHelpers.assertFieldValue(
assertFieldValue(
this.field, suiteInfo.expectedValue,
String(suiteInfo.expectedValue).toLowerCase());
});
+12 -10
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldColour');
const {createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Colour Fields', function() {
@@ -87,7 +89,7 @@ suite('Colour Fields', function() {
* @param {FieldTemplate} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, defaultFieldValue, defaultTextValue);
assertFieldValue(field, defaultFieldValue, defaultTextValue);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -95,15 +97,15 @@ suite('Colour Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(
assertFieldValue(
field, testCase.expectedValue, testCase.expectedText);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldColour, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldColour, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -112,25 +114,25 @@ suite('Colour Fields', function() {
setup(function() {
this.field = new Blockly.FieldColour();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue,
defaultTextValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('#bcbcbc');
testHelpers.assertFieldValue(this.field, '#bcbcbc', '#bcbcbc');
assertFieldValue(this.field, '#bcbcbc', '#bcbcbc');
});
});
suite('Value -> New Value', function() {
setup(function() {
this.field = new Blockly.FieldColour('#aaaaaa');
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, '#aaaaaa', '#aaa');
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('#bcbcbc');
testHelpers.assertFieldValue(this.field, '#bcbcbc', '#bcbcbc');
assertFieldValue(this.field, '#bcbcbc', '#bcbcbc');
});
});
});
@@ -161,7 +163,7 @@ suite('Colour Fields', function() {
});
test('New Value', function() {
this.field.setValue(suiteInfo.value);
testHelpers.assertFieldValue(
assertFieldValue(
this.field, suiteInfo.expectedValue, suiteInfo.expectedText);
});
});
+11 -9
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldDropdown');
const {createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Dropdown Fields', function() {
@@ -74,14 +76,14 @@ suite('Dropdown Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue, testCase.expectedText);
assertFieldValue(field, testCase.expectedValue, testCase.expectedText);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldDropdown, validValueCreationTestCases,
invalidValueCreationTestCases, validTestCaseAssertField);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldDropdown, validValueCreationTestCases,
invalidValueCreationTestCases, validTestCaseAssertField);
@@ -107,12 +109,12 @@ suite('Dropdown Fields', function() {
this.field = new Blockly.FieldDropdown(
[['a', 'A'], ['b', 'B'], ['c', 'C']]);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueSetValueTestCases, invalidValueSetValueTestCases, 'A', 'a');
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('B');
testHelpers.assertFieldValue(this.field, 'B', 'b');
assertFieldValue(this.field, 'B', 'b');
});
});
@@ -133,7 +135,7 @@ suite('Dropdown Fields', function() {
});
test('New Value', function() {
this.dropdownField.setValue('1B');
testHelpers.assertFieldValue(this.dropdownField, '1A', '1a');
assertFieldValue(this.dropdownField, '1A', '1a');
});
});
suite('Force 1s Validator', function() {
@@ -144,7 +146,7 @@ suite('Dropdown Fields', function() {
});
test('New Value', function() {
this.dropdownField.setValue('2B');
testHelpers.assertFieldValue(this.dropdownField, '1B', '1b');
assertFieldValue(this.dropdownField, '1B', '1b');
});
});
suite('Returns Undefined Validator', function() {
@@ -153,7 +155,7 @@ suite('Dropdown Fields', function() {
});
test('New Value', function() {
this.dropdownField.setValue('1B');
testHelpers.assertFieldValue(this.dropdownField, '1B', '1b');
assertFieldValue(this.dropdownField, '1B', '1b');
});
});
});
+9 -8
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.fieldImage');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Image Fields', function() {
@@ -56,14 +57,14 @@ suite('Image Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue, testCase.expectedText);
assertFieldValue(field, testCase.expectedValue, testCase.expectedText);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldImage, validValueCreationTestCases, invalidValueTestCases,
validTestCaseAssertField);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldImage, validValueCreationTestCases, invalidValueTestCases,
validTestCaseAssertField);
@@ -80,7 +81,7 @@ suite('Image Fields', function() {
setup(function() {
this.field = new Blockly.FieldImage('src', 1, 1, 'alt');
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueSetValueTestCases, invalidValueTestCases, 'src', 'alt');
});
@@ -126,15 +127,15 @@ suite('Image Fields', function() {
});
test('Null', function() {
this.imageField.setAlt(null);
testHelpers.assertFieldValue(this.imageField, 'src', '');
assertFieldValue(this.imageField, 'src', '');
});
test('Empty String', function() {
this.imageField.setAlt('');
testHelpers.assertFieldValue(this.imageField, 'src', '');
assertFieldValue(this.imageField, 'src', '');
});
test('Good Alt', function() {
this.imageField.setAlt('newAlt');
testHelpers.assertFieldValue(this.imageField, 'src', 'newAlt');
assertFieldValue(this.imageField, 'src', 'newAlt');
});
});
test('JS Configuration - Simple', function() {
+11 -9
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldLabelSerialization');
const {createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Label Serializable Fields', function() {
@@ -53,7 +55,7 @@ suite('Label Serializable Fields', function() {
* @param {!Blockly.FieldLabelSerializable} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, defaultFieldValue);
assertFieldValue(field, defaultFieldValue);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -61,14 +63,14 @@ suite('Label Serializable Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue);
assertFieldValue(field, testCase.expectedValue);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldLabelSerializable, validValueTestCases,
invalidValueTestCases, validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldLabelSerializable, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -77,12 +79,12 @@ suite('Label Serializable Fields', function() {
setup(function() {
this.field = new Blockly.FieldLabelSerializable();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
suite('Value -> New Value', function() {
@@ -90,12 +92,12 @@ suite('Label Serializable Fields', function() {
setup(function() {
this.field = new Blockly.FieldLabelSerializable(initialValue);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, initialValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
});
+11 -9
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldLabel');
const {createTestBlock, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {createTestBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Label Fields', function() {
@@ -53,7 +55,7 @@ suite('Label Fields', function() {
* @param {!Blockly.FieldLabel} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, defaultFieldValue);
assertFieldValue(field, defaultFieldValue);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -61,14 +63,14 @@ suite('Label Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue);
assertFieldValue(field, testCase.expectedValue);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldLabel, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldLabel, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -77,12 +79,12 @@ suite('Label Fields', function() {
setup(function() {
this.field = new Blockly.FieldLabel();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
suite('Value -> New Value', function() {
@@ -90,12 +92,12 @@ suite('Label Fields', function() {
setup(function() {
this.field = new Blockly.FieldLabel(initialValue);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, initialValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
});
+13 -10
View File
@@ -6,7 +6,10 @@
goog.module('Blockly.test.fieldMultiline');
const {createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {runCodeGenerationTestSuites} = goog.require('Blockly.test.helpers.codeGeneration');
suite('Multiline Input Fields', function() {
@@ -55,7 +58,7 @@ suite('Multiline Input Fields', function() {
* @param {!Blockly.FieldMultilineInput} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, defaultFieldValue);
assertFieldValue(field, defaultFieldValue);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -63,14 +66,14 @@ suite('Multiline Input Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue);
assertFieldValue(field, testCase.expectedValue);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldMultilineInput, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldMultilineInput, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -79,12 +82,12 @@ suite('Multiline Input Fields', function() {
setup(function() {
this.field = new Blockly.FieldMultilineInput();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
suite('Value -> New Value', function() {
@@ -92,12 +95,12 @@ suite('Multiline Input Fields', function() {
setup(function() {
this.field = new Blockly.FieldMultilineInput(initialValue);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, initialValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
});
@@ -156,7 +159,7 @@ suite('Multiline Input Fields', function() {
createBlock: createBlockFn('bark bark\n bark bark bark\n bark bar bark bark\n')},
]},
];
testHelpers.runCodeGenerationTestSuites(testSuites);
runCodeGenerationTestSuites(testSuites);
});
suite('Serialization', function() {
+16 -13
View File
@@ -6,7 +6,10 @@
goog.module('Blockly.test.fieldNumber');
const {defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {runTestCases} = goog.require('Blockly.test.helpers.common');
suite('Number Fields', function() {
@@ -64,7 +67,7 @@ suite('Number Fields', function() {
*/
function assertNumberField(field, expectedMin, expectedMax,
expectedPrecision, expectedValue) {
testHelpers.assertFieldValue(field, expectedValue);
assertFieldValue(field, expectedValue);
chai.assert.equal(field.getMin(), expectedMin, 'Min');
chai.assert.equal(field.getMax(), expectedMax, 'Max');
chai.assert.equal(
@@ -88,11 +91,11 @@ suite('Number Fields', function() {
testCase.expectedValue, testCase.expectedValue);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldNumber, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldNumber, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -101,7 +104,7 @@ suite('Number Fields', function() {
setup(function() {
this.field = new Blockly.FieldNumber();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue);
});
suite('Value -> New Value', function() {
@@ -109,7 +112,7 @@ suite('Number Fields', function() {
setup(function() {
this.field = new Blockly.FieldNumber(initialValue);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, initialValue);
});
suite('Constraints', function() {
@@ -127,11 +130,11 @@ suite('Number Fields', function() {
expectedValue: 123},
];
suite('Precision', function() {
testHelpers.runTestCases(testCases, function(testCase) {
runTestCases(testCases, function(testCase) {
return function() {
const field = Blockly.FieldNumber.fromJson(testCase.json);
field.setValue(testCase.value);
testHelpers.assertFieldValue(field, testCase.expectedValue);
assertFieldValue(field, testCase.expectedValue);
};
});
test('Null', function() {
@@ -144,7 +147,7 @@ suite('Number Fields', function() {
const field = Blockly.FieldNumber.fromJson(testCase.json);
testCase.values.forEach(function(value, i) {
field.setValue(value);
testHelpers.assertFieldValue(
assertFieldValue(
field, testCase.expectedValues[i]);
});
};
@@ -158,7 +161,7 @@ suite('Number Fields', function() {
{title: '+10', json: {min: 10}, values: [-20, 0, 20],
expectedValues: [10, 10, 20]},
];
testHelpers.runTestCases(testCases, setValueBoundsTestFn);
runTestCases(testCases, setValueBoundsTestFn);
test('Null', function() {
const field = Blockly.FieldNumber.fromJson({min: null});
chai.assert.equal(field.getMin(), -Infinity);
@@ -173,7 +176,7 @@ suite('Number Fields', function() {
{title: '+10', json: {max: 10}, values: [-20, 0, 20],
expectedValues: [-20, 0, 10]},
];
testHelpers.runTestCases(testCases, setValueBoundsTestFn);
runTestCases(testCases, setValueBoundsTestFn);
test('Null', function() {
const field = Blockly.FieldNumber.fromJson({max: null});
chai.assert.equal(field.getMax(), Infinity);
@@ -217,12 +220,12 @@ suite('Number Fields', function() {
this.field.isBeingEdited_ = true;
this.field.htmlInput_.value = String(suiteInfo.value);
this.field.onHtmlInputChange_(null);
testHelpers.assertFieldValue(
assertFieldValue(
this.field, suiteInfo.expectedValue, String(suiteInfo.value));
});
test('When Not Editing', function() {
this.field.setValue(suiteInfo.value);
testHelpers.assertFieldValue(this.field, suiteInfo.expectedValue);
assertFieldValue(this.field, suiteInfo.expectedValue);
});
});
});
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.fieldRegistry');
const {createDeprecationWarningStub, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {createDeprecationWarningStub} = goog.require('Blockly.test.helpers.warnings');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Field Registry', function() {
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.fieldTest');
const {addBlockTypeToCleanup, addMessageToCleanup, createDeprecationWarningStub, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {addBlockTypeToCleanup, addMessageToCleanup, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {createDeprecationWarningStub} = goog.require('Blockly.test.helpers.warnings');
suite('Abstract Fields', function() {
+13 -11
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldTextInput');
const {createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Text Input Fields', function() {
@@ -53,7 +55,7 @@ suite('Text Input Fields', function() {
* @param {!Blockly.FieldTextInput} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, defaultFieldValue);
assertFieldValue(field, defaultFieldValue);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -61,14 +63,14 @@ suite('Text Input Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, testCase.expectedValue);
assertFieldValue(field, testCase.expectedValue);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldTextInput, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldTextInput, validValueTestCases, invalidValueTestCases,
validTestCaseAssertField, assertFieldDefault);
@@ -77,12 +79,12 @@ suite('Text Input Fields', function() {
setup(function() {
this.field = new Blockly.FieldTextInput();
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, defaultFieldValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
suite('Value -> New Value', function() {
@@ -90,12 +92,12 @@ suite('Text Input Fields', function() {
setup(function() {
this.field = new Blockly.FieldTextInput(initialValue);
});
testHelpers.runSetValueTests(
runSetValueTests(
validValueTestCases, invalidValueTestCases, initialValue);
test('With source block', function() {
this.field.setSourceBlock(createTestBlock());
this.field.setValue('value');
testHelpers.assertFieldValue(this.field, 'value');
assertFieldValue(this.field, 'value');
});
});
});
@@ -136,12 +138,12 @@ suite('Text Input Fields', function() {
this.field.isBeingEdited_ = true;
this.field.htmlInput_.value = suiteInfo.value;
this.field.onHtmlInputChange_(null);
testHelpers.assertFieldValue(
assertFieldValue(
this.field, suiteInfo.expectedValue, suiteInfo.value);
});
test('When Not Editing', function() {
this.field.setValue(suiteInfo.value);
testHelpers.assertFieldValue(this.field, suiteInfo.expectedValue);
assertFieldValue(this.field, suiteInfo.expectedValue);
});
});
});
+11 -9
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.fieldVariable');
const {createGenUidStubWithReturns, createTestBlock, defineRowBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertFieldValue, runConstructorSuiteTests, runFromJsonSuiteTests, runSetValueTests} = goog.require('Blockly.test.helpers.fields');
const {createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {createTestBlock, defineRowBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Variable Fields', function() {
@@ -83,7 +85,7 @@ suite('Variable Fields', function() {
* @param {!Blockly.FieldVariable} field The field to check.
*/
const assertFieldDefault = function(field) {
testHelpers.assertFieldValue(field, FAKE_ID, defaultFieldName);
assertFieldValue(field, FAKE_ID, defaultFieldName);
};
/**
* Asserts that the field properties are correct based on the test case.
@@ -91,15 +93,15 @@ suite('Variable Fields', function() {
* @param {!FieldValueTestCase} testCase The test case.
*/
const validTestCaseAssertField = function(field, testCase) {
testHelpers.assertFieldValue(field, FAKE_ID, testCase.expectedText);
assertFieldValue(field, FAKE_ID, testCase.expectedText);
};
testHelpers.runConstructorSuiteTests(
runConstructorSuiteTests(
Blockly.FieldVariable, validValueCreationTestCases,
invalidValueCreationTestCases,
validTestCaseAssertField, assertFieldDefault, customCreateWithJs);
testHelpers.runFromJsonSuiteTests(
runFromJsonSuiteTests(
Blockly.FieldVariable, validValueCreationTestCases,
invalidValueCreationTestCases,
validTestCaseAssertField, assertFieldDefault, customCreateWithJson);
@@ -149,7 +151,7 @@ suite('Variable Fields', function() {
teardown(function() {
console.warn = this.nativeConsoleWarn;
});
testHelpers.runSetValueTests(validValueTestCases, invalidValueTestCases,
runSetValueTests(validValueTestCases, invalidValueTestCases,
FAKE_ID, defaultFieldName);
});
@@ -215,7 +217,7 @@ suite('Variable Fields', function() {
});
test('New Value', function() {
this.variableField.setValue('id2');
testHelpers.assertFieldValue(this.variableField, 'id1', 'name1');
assertFieldValue(this.variableField, 'id1', 'name1');
});
});
suite('Force \'id\' ID Validator', function() {
@@ -228,7 +230,7 @@ suite('Variable Fields', function() {
// Must create the var so that the field doesn't throw an error.
this.workspace.createVariable('thing2', null, 'other2');
this.variableField.setValue('other2');
testHelpers.assertFieldValue(this.variableField, 'id2', 'name2');
assertFieldValue(this.variableField, 'id2', 'name2');
});
});
suite('Returns Undefined Validator', function() {
@@ -237,7 +239,7 @@ suite('Variable Fields', function() {
});
test('New Value', function() {
this.variableField.setValue('id2');
testHelpers.assertFieldValue(this.variableField, 'id2', 'name2');
assertFieldValue(this.variableField, 'id2', 'name2');
});
});
});
+2 -2
View File
@@ -6,8 +6,8 @@
goog.module('Blockly.test.flyout');
const {defineStackBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {getBasicToolbox, getChildItem, getCollapsibleItem, getDeeplyNestedJSON, getInjectedToolbox, getNonCollapsibleItem, getProperSimpleJson, getSeparator, getSimpleJson, getXmlArray} = goog.require('Blockly.test.toolboxHelpers');
const {defineStackBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {getBasicToolbox, getChildItem, getCollapsibleItem, getDeeplyNestedJSON, getInjectedToolbox, getNonCollapsibleItem, getProperSimpleJson, getSeparator, getSimpleJson, getXmlArray} = goog.require('Blockly.test.helpers.toolboxDefinitions');
suite('Flyout', function() {
+1 -1
View File
@@ -11,7 +11,7 @@ goog.require('Blockly.JavaScript');
goog.require('Blockly.Lua');
goog.require('Blockly.PHP');
goog.require('Blockly.Python');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Generator', function() {
+4 -1
View File
@@ -6,8 +6,11 @@
goog.module('Blockly.test.gesture');
const {assertEventFired, assertEventNotFired} = goog.require('Blockly.test.helpers.events');
const {defineBasicBlockWithField} = goog.require('Blockly.test.helpers.blockDefinitions');
const {dispatchPointerEvent} = goog.require('Blockly.test.helpers.userInput');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, assertEventNotFired, defineBasicBlockWithField, dispatchPointerEvent, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Gesture', function() {
+1 -2
View File
@@ -24,7 +24,6 @@
<script src="../../node_modules/chai/chai.js"></script>
<script src="../../node_modules/mocha/mocha.js"></script>
<script src="../../node_modules/sinon/pkg/sinon.js"></script>
<script src="../../node_modules/@blockly/dev-tools/dist/index.js"></script>
<script>
mocha.setup({
ui: 'tdd'
@@ -173,7 +172,7 @@
<block type="test_field_block"></block>
</xml>
<script>
<script type="module">
mocha.run(function(failures) {
var failureDiv = document.getElementById('failureCount');
failureDiv.setAttribute('tests_failed', failures);
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.input');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Inputs', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.insertionMarker');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('InsertionMarkers', function() {
+2 -1
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.jsoDeserialization');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {assertEventFired} = goog.require('Blockly.test.helpers.events');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
suite('JSO Deserialization', function() {
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.jsoSerialization');
const {defineStackBlock, defineRowBlock, defineStatementBlock, createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {defineRowBlock, defineStackBlock, defineStatementBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('JSO Serialization', function() {
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.json');
const {addMessageToCleanup, assertNoWarnings, assertWarnings, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {addMessageToCleanup, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {assertNoWarnings, assertWarnings} = goog.require('Blockly.test.helpers.warnings');
suite('JSON Block Definitions', function() {
+3 -1
View File
@@ -6,7 +6,9 @@
goog.module('Blockly.test.keydown');
const {createKeyDownEvent, defineStackBlock, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {createKeyDownEvent} = goog.require('Blockly.test.helpers.userInput');
const {defineStackBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Key Down', function() {
+3 -2
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.logicTernary');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const eventUtils = goog.require('Blockly.Events.utils');
const {runSerializationTestSuite} = goog.require('Blockly.test.helpers.serialization');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Logic ternary', function() {
@@ -73,7 +74,7 @@ suite('Logic ternary', function() {
},
},
];
testHelpers.runSerializationTestSuite(testCases);
runSerializationTestSuite(testCases);
suite('Connections', function() {
function connectParentAndCheckConnections(
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.metrics');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Metrics', function() {
+2 -1
View File
@@ -7,7 +7,8 @@
goog.module('Blockly.test.mutator');
const {createRenderedBlock, defineMutatorBlocks, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {createRenderedBlock, defineMutatorBlocks} = goog.require('Blockly.test.helpers.blockDefinitions');
suite('Mutator', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.names');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Names', function() {
+4 -3
View File
@@ -8,8 +8,9 @@ goog.module('Blockly.test.procedures');
goog.require('Blockly');
goog.require('Blockly.Msg');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertCallBlockStructure, assertDefBlockStructure, createProcDefBlock, createProcCallBlock} = goog.require('Blockly.test.procedureHelpers');
const {assertCallBlockStructure, assertDefBlockStructure, createProcDefBlock, createProcCallBlock} = goog.require('Blockly.test.helpers.procedures');
const {runSerializationTestSuite} = goog.require('Blockly.test.helpers.serialization');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Procedures', function() {
@@ -1203,7 +1204,7 @@ suite('Procedures', function() {
},
},
];
testHelpers.runSerializationTestSuite(testCases);
runSerializationTestSuite(testCases);
});
});
});
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.registry');
const {assertWarnings, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {assertWarnings} = goog.require('Blockly.test.helpers.warnings');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Registry', function() {
+7 -5
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.serialization');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {TestCase, TestSuite, runTestCases, runTestSuites} = goog.require('Blockly.test.helpers.common');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
// TODO: Move this into samples as part of the dev-tools package.
@@ -23,7 +24,7 @@ function SerializerTestCase(title, xml) {
this.title = title;
this.xml = xml;
}
SerializerTestCase.prototype = new testHelpers.TestCase();
SerializerTestCase.prototype = new TestCase();
/**
* The XML we want to ensure round-trips through the serializer.
@@ -39,7 +40,7 @@ SerializerTestCase.prototype.xml = '';
function SerializerTestSuite(title) {
this.title = title;
}
SerializerTestSuite.prototype = new testHelpers.TestSuite();
SerializerTestSuite.prototype = new TestSuite();
const Serializer = new SerializerTestSuite('Serializer');
@@ -166,6 +167,7 @@ Serializer.Attributes.testSuites = [
];
Serializer.Fields = new SerializerTestSuite('Fields');
Serializer.Fields.skip = true;
Serializer.Fields.Angle = new SerializerTestSuite('Angle');
Serializer.Fields.Angle.Simple = new SerializerTestCase('Simple',
@@ -1818,9 +1820,9 @@ const runSerializerTestSuite = (serializer, deserializer, testSuite) => {
sharedTestTeardown.call(this);
});
testHelpers.runTestSuites(
runTestSuites(
testSuite.testSuites, createTestCaseFunction);
testHelpers.runTestCases(testSuite.testCases, createTestFunction);
runTestCases(testSuite.testCases, createTestFunction);
});
};
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.shortcutRegistry');
const {createKeyDownEvent, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {createKeyDownEvent} = goog.require('Blockly.test.helpers.userInput');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Keyboard Shortcut Registry Test', function() {
-717
View File
@@ -1,717 +0,0 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.module('Blockly.test.helpers');
const {KeyCodes} = goog.require('Blockly.utils.KeyCodes');
const eventUtils = goog.require('Blockly.Events.utils');
const {Blocks} = goog.require('Blockly.blocks');
/**
* Check if a variable with the given values exists.
* @param {Blockly.Workspace|Blockly.VariableMap} container The workspace or
* variableMap the checked variable belongs to.
* @param {!string} name The expected name of the variable.
* @param {!string} type The expected type of the variable.
* @param {!string} id The expected id of the variable.
*/
function assertVariableValues(container, name, type, id) {
const variable = container.getVariableById(id);
chai.assert.isDefined(variable);
chai.assert.equal(variable.name, name);
chai.assert.equal(variable.type, type);
chai.assert.equal(variable.getId(), id);
}
exports.assertVariableValues = assertVariableValues;
/**
* Asserts that the given function logs the provided warning messages.
* @param {function()} innerFunc The function to call.
* @param {Array<!RegExp>|!RegExp} messages A list of regex for the expected
* messages (in the expected order).
*/
function assertWarnings(innerFunc, messages) {
if (!Array.isArray(messages)) {
messages = [messages];
}
const warnings = testHelpers.captureWarnings(innerFunc);
chai.assert.lengthOf(warnings, messages.length);
messages.forEach((message, i) => {
chai.assert.match(warnings[i], message);
});
}
exports.assertWarnings = assertWarnings;
/**
* Asserts that the given function logs no warning messages.
* @param {function()} innerFunc The function to call.
*/
function assertNoWarnings(innerFunc) {
assertWarnings(innerFunc, []);
}
exports.assertNoWarnings = assertNoWarnings;
/**
* Stubs Blockly.utils.deprecation.warn call.
* @return {!SinonStub} The created stub.
*/
function createDeprecationWarningStub() {
return sinon.stub(Blockly.utils.deprecation, 'warn');
}
exports.createDeprecationWarningStub = createDeprecationWarningStub;
/**
* Asserts whether the given deprecation warning stub or call was called with
* the expected functionName.
* @param {!SinonSpy|!SinonSpyCall} spyOrSpyCall The spy or spy call to use.
* @param {string} functionName The function name to check that the given spy or
* spy call was called with.
*/
function assertDeprecationWarningCall(spyOrSpyCall, functionName) {
sinon.assert.calledWith(spyOrSpyCall, functionName);
}
exports.assertDeprecationWarningCall = assertDeprecationWarningCall;
/**
* Asserts that there was a single deprecation warning call with the given
* functionName passed.
* @param {!SinonSpy} spy The spy to use.
* @param {string} functionName The function name to check that the given spy
* was called with.
*/
function assertSingleDeprecationWarningCall(spy, functionName) {
sinon.assert.calledOnce(spy);
assertDeprecationWarningCall(spy.getCall(0), functionName);
}
exports.assertSingleDeprecationWarningCall = assertSingleDeprecationWarningCall;
/**
* Safely disposes of Blockly workspace, logging any errors.
* Assumes that sharedTestSetup has also been called. This should be called
* using workspaceTeardown.call(this).
* @param {!Blockly.Workspace} workspace The workspace to dispose.
*/
function workspaceTeardown(workspace) {
try {
this.clock.runAll(); // Run all queued setTimeout calls.
workspace.dispose();
this.clock.runAll(); // Run all remaining queued setTimeout calls.
} catch (e) {
const testRef = this.currentTest || this.test;
console.error(testRef.fullTitle() + '\n', e);
}
}
exports.workspaceTeardown = workspaceTeardown;
/**
* Creates stub for Blockly.Events.fire that advances the clock forward after
* the event fires so it is processed immediately instead of on a timeout.
* @param {!SinonClock} clock The sinon clock.
* @return {!SinonStub} The created stub.
* @private
*/
function createEventsFireStubFireImmediately_(clock) {
const stub = sinon.stub(eventUtils, 'fire');
stub.callsFake(function(event) {
// Call original method.
stub.wrappedMethod.call(this, ...arguments);
// Advance clock forward to run any queued events.
clock.runAll();
});
return stub;
}
/**
* Adds message to shared cleanup object so that it is cleaned from
* Blockly.Messages global in sharedTestTeardown.
* @param {!Object} sharedCleanupObj The shared cleanup object created in
* sharedTestSetup.
* @param {string} message The message to add to shared cleanup object.
*/
function addMessageToCleanup(sharedCleanupObj, message) {
sharedCleanupObj.messagesCleanup_.push(message);
}
exports.addMessageToCleanup = addMessageToCleanup;
/**
* Adds block type to shared cleanup object so that it is cleaned from
* Blockly.Blocks global in sharedTestTeardown.
* @param {!Object} sharedCleanupObj The shared cleanup object created in
* sharedTestSetup.
* @param {string} blockType The block type to add to shared cleanup object.
*/
function addBlockTypeToCleanup(sharedCleanupObj, blockType) {
sharedCleanupObj.blockTypesCleanup_.push(blockType);
}
exports.addBlockTypeToCleanup = addBlockTypeToCleanup;
/**
* Wraps Blockly.defineBlocksWithJsonArray using stub in order to keep track of
* block types passed in to method on shared cleanup object so they are cleaned
* from Blockly.Blocks global in sharedTestTeardown.
* @param {!Object} sharedCleanupObj The shared cleanup object created in
* sharedTestSetup.
* @private
*/
function wrapDefineBlocksWithJsonArrayWithCleanup_(sharedCleanupObj) {
const stub = sinon.stub(Blockly, 'defineBlocksWithJsonArray');
stub.callsFake(function(jsonArray) {
if (jsonArray) {
jsonArray.forEach((jsonBlock) => {
if (jsonBlock) {
addBlockTypeToCleanup(sharedCleanupObj, jsonBlock['type']);
}
});
}
// Calls original method.
stub.wrappedMethod.call(this, ...arguments);
});
}
/**
* Shared setup method that sets up fake timer for clock so that pending
* setTimeout calls can be cleared in test teardown along with other common
* stubs. Should be called in setup of outermost suite using
* sharedTestSetup.call(this).
* The sinon fake timer defined on this.clock_ should not be reset in tests to
* avoid causing issues with cleanup in sharedTestTeardown.
*
* Stubs created in this setup (unless disabled by options passed):
* - Blockly.Events.fire - this.eventsFireStub - wraps fire event to trigger
* fireNow_ call immediately, rather than on timeout
* - Blockly.defineBlocksWithJsonArray - thin wrapper that adds logic to keep
* track of block types defined so that they can be undefined in
* sharedTestTeardown and calls original method.
*
* @param {Object<string, boolean>} options Options to enable/disable setup
* of certain stubs.
*/
function sharedTestSetup(options = {}) {
this.sharedSetupCalled_ = true;
// Sandbox created for greater control when certain stubs are cleared.
this.sharedSetupSandbox_ = sinon.createSandbox();
this.clock = this.sharedSetupSandbox_.useFakeTimers();
if (options['fireEventsNow'] === undefined || options['fireEventsNow']) {
// Stubs event firing unless passed option "fireEventsNow: false"
this.eventsFireStub = createEventsFireStubFireImmediately_(this.clock);
}
this.sharedCleanup = {
blockTypesCleanup_: [],
messagesCleanup_: [],
};
this.blockTypesCleanup_ = this.sharedCleanup.blockTypesCleanup_;
this.messagesCleanup_ = this.sharedCleanup.messagesCleanup_;
wrapDefineBlocksWithJsonArrayWithCleanup_(this.sharedCleanup);
}
exports.sharedTestSetup = sharedTestSetup;
/**
* Shared cleanup method that clears up pending setTimeout calls, disposes of
* workspace, and resets global variables. Should be called in setup of
* outermost suite using sharedTestTeardown.call(this).
*/
function sharedTestTeardown() {
const testRef = this.currentTest || this.test;
if (!this.sharedSetupCalled_) {
console.error('"' + testRef.fullTitle() + '" did not call sharedTestSetup');
}
try {
if (this.workspace) {
workspaceTeardown.call(this, this.workspace);
this.workspace = null;
} else {
this.clock.runAll(); // Run all queued setTimeout calls.
}
} catch (e) {
console.error(testRef.fullTitle() + '\n', e);
} finally {
// Clear Blockly.Event state.
eventUtils.setGroup(false);
while (!eventUtils.isEnabled()) {
eventUtils.enable();
}
eventUtils.setRecordUndo(true);
if (eventUtils.TEST_ONLY.FIRE_QUEUE.length) {
// If this happens, it may mean that some previous test is missing cleanup
// (i.e. a previous test added an event to the queue on a timeout that
// did not use a stubbed clock).
eventUtils.TEST_ONLY.FIRE_QUEUE.length = 0;
console.warn('"' + testRef.fullTitle() +
'" needed cleanup of Blockly.Events.TEST_ONLY.FIRE_QUEUE. This may ' +
'indicate leakage from an earlier test');
}
// Restore all stubbed methods.
this.sharedSetupSandbox_.restore();
sinon.restore();
const blockTypes = this.sharedCleanup.blockTypesCleanup_;
for (let i = 0; i < blockTypes.length; i++) {
delete Blocks[blockTypes[i]];
}
const messages = this.sharedCleanup.messagesCleanup_;
for (let i = 0; i < messages.length; i++) {
delete Blockly.Msg[messages[i]];
}
Blockly.WidgetDiv.testOnly_setDiv(null);
}
}
exports.sharedTestTeardown = sharedTestTeardown;
/**
* Creates stub for Blockly.utils.genUid that returns the provided id or ids.
* Recommended to also assert that the stub is called the expected number of
* times.
* @param {string|!Array<string>} returnIds The return values to use for the
* created stub. If a single value is passed, then the stub always returns
* that value.
* @return {!SinonStub} The created stub.
*/
function createGenUidStubWithReturns(returnIds) {
const stub = sinon.stub(Blockly.utils.idGenerator.TEST_ONLY, "genUid");
if (Array.isArray(returnIds)) {
for (let i = 0; i < returnIds.length; i++) {
stub.onCall(i).returns(returnIds[i]);
}
} else {
stub.returns(returnIds);
}
return stub;
}
exports.createGenUidStubWithReturns = createGenUidStubWithReturns;
/**
* Creates spy for workspace fireChangeListener
* @param {!Blockly.Workspace} workspace The workspace to spy fireChangeListener
* calls on.
* @return {!SinonSpy} The created spy.
*/
function createFireChangeListenerSpy(workspace) {
return sinon.spy(workspace, 'fireChangeListener');
}
exports.createFireChangeListenerSpy = createFireChangeListenerSpy;
/**
* Asserts whether the given xml property has the expected property.
* @param {!Node} xmlValue The xml value to check.
* @param {!Node|string} expectedValue The expected value.
* @param {string=} message Optional message to use in assert message.
* @private
*/
function assertXmlPropertyEqual_(xmlValue, expectedValue, message) {
const value = Blockly.Xml.domToText(xmlValue);
if (expectedValue instanceof Node) {
expectedValue = Blockly.Xml.domToText(expectedValue);
}
chai.assert.equal(value, expectedValue, message);
}
/**
* Asserts that the given object has the expected xml properties.
* @param {Object} obj The object to check.
* @param {Object<string, Node|string>} expectedXmlProperties The expected xml
* properties.
* @private
*/
function assertXmlProperties_(obj, expectedXmlProperties) {
Object.keys(expectedXmlProperties).map((key) => {
const value = obj[key];
const expectedValue = expectedXmlProperties[key];
if (expectedValue === undefined) {
chai.assert.isUndefined(value,
'Expected ' + key + ' property to be undefined');
return;
}
chai.assert.exists(value, 'Expected ' + key + ' property to exist');
assertXmlPropertyEqual_(value, expectedValue, 'Checking property ' + key);
});
}
/**
* Whether given key indicates that the property is xml.
* @param {string} key The key to check.
* @return {boolean} Whether the given key is for xml property.
* @private
*/
function isXmlProperty_(key) {
return key.toLowerCase().endsWith('xml');
}
/**
* Asserts that the given event has the expected values.
* @param {!Blockly.Events.Abstract} event The event to check.
* @param {string} expectedType Expected type of event fired.
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string} expectedBlockId Expected block id of event fired.
* @param {!Object<string, *>} expectedProperties Map of of additional expected
* properties to check on fired event.
* @param {boolean=} [isUiEvent=false] Whether the event is a UI event.
* @param {string=} message Optional message to prepend assert messages.
*/
function assertEventEquals(event, expectedType,
expectedWorkspaceId, expectedBlockId, expectedProperties, isUiEvent = false, message) {
let prependMessage = message ? message + ' ' : '';
prependMessage += 'Event fired ';
chai.assert.equal(event.type, expectedType,
prependMessage + 'type');
chai.assert.equal(event.workspaceId, expectedWorkspaceId,
prependMessage + 'workspace id');
chai.assert.equal(event.blockId, expectedBlockId,
prependMessage + 'block id');
Object.keys(expectedProperties).map((key) => {
const value = event[key];
const expectedValue = expectedProperties[key];
if (expectedValue === undefined) {
chai.assert.isUndefined(value, prependMessage + key);
return;
}
chai.assert.exists(value, prependMessage + key);
if (isXmlProperty_(key)) {
assertXmlPropertyEqual_(value, expectedValue,
prependMessage + key);
} else {
chai.assert.equal(value, expectedValue,
prependMessage + key);
}
});
if (isUiEvent) {
chai.assert.isTrue(event.isUiEvent);
} else {
chai.assert.isFalse(event.isUiEvent);
}
}
exports.assertEventEquals = assertEventEquals;
/**
* Asserts that an event with the given values was fired.
* @param {!SinonSpy|!SinonSpyCall} spy The spy or spy call to use.
* @param {function(new:Blockly.Events.Abstract)} instanceType Expected instance
* type of event fired.
* @param {!Object<string, *>} expectedProperties Map of of expected properties
* to check on fired event.
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string=} expectedBlockId Expected block id of event fired.
*/
function assertEventFired(spy, instanceType, expectedProperties,
expectedWorkspaceId, expectedBlockId) {
expectedProperties = Object.assign({
workspaceId: expectedWorkspaceId,
blockId: expectedBlockId,
}, expectedProperties);
const expectedEvent =
sinon.match.instanceOf(instanceType).and(sinon.match(expectedProperties));
sinon.assert.calledWith(spy, expectedEvent);
}
exports.assertEventFired = assertEventFired;
/**
* Asserts that an event with the given values was not fired.
* @param {!SpyCall} spy The spy to use.
* @param {function(new:Blockly.Events.Abstract)} instanceType Expected instance
* type of event fired.
* @param {!Object<string, *>} expectedProperties Map of of expected properties
* to check on fired event.
* @param {string=} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string=} expectedBlockId Expected block id of event fired.
*/
function assertEventNotFired(spy, instanceType, expectedProperties,
expectedWorkspaceId, expectedBlockId) {
if (expectedWorkspaceId !== undefined) {
expectedProperties.workspaceId = expectedWorkspaceId;
}
if (expectedBlockId !== undefined) {
expectedProperties.blockId = expectedBlockId;
}
const expectedEvent =
sinon.match.instanceOf(instanceType).and(sinon.match(expectedProperties));
sinon.assert.neverCalledWith(spy, expectedEvent);
}
exports.assertEventNotFired = assertEventNotFired;
/**
* Filters out xml properties from given object based on key.
* @param {Object<string, *>} properties The properties to filter.
* @return {Array<Object<string, *>>} A list containing split non
* xml properties and xml properties. [Object<string, *>, Object<string, *>]
* @private
*/
function splitByXmlProperties_(properties) {
const xmlProperties = {};
const nonXmlProperties = {};
Object.keys(properties).forEach((key) => {
if (isXmlProperty_(key)) {
xmlProperties[key] = properties[key];
return false;
} else {
nonXmlProperties[key] = properties[key];
}
});
return [nonXmlProperties, xmlProperties];
}
/**
* Asserts that the event passed to the nth call of the given spy has the
* expected values. Assumes that the event is passed as the first argument.
* @param {!SinonSpy} spy The spy to use.
* @param {number} n Which call to check.
* @param {function(new:Blockly.Events.Abstract)} instanceType Expected instance
* type of event fired.
* @param {Object<string, *>} expectedProperties Map of of expected properties
* to check on fired event.
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string=} expectedBlockId Expected block id of event fired.
*/
function assertNthCallEventArgEquals(spy, n, instanceType, expectedProperties,
expectedWorkspaceId, expectedBlockId) {
const nthCall = spy.getCall(n);
const splitProperties = splitByXmlProperties_(expectedProperties);
const nonXmlProperties = splitProperties[0];
const xmlProperties = splitProperties[1];
assertEventFired(nthCall, instanceType, nonXmlProperties, expectedWorkspaceId,
expectedBlockId);
const eventArg = nthCall.firstArg;
assertXmlProperties_(eventArg, xmlProperties);
}
exports.assertNthCallEventArgEquals = assertNthCallEventArgEquals;
function defineStackBlock(name = 'stack_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "",
"previousStatement": null,
"nextStatement": null,
}]);
}
exports.defineStackBlock = defineStackBlock;
function defineRowBlock(name = 'row_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "%1",
"args0": [
{
"type": "input_value",
"name": "INPUT",
},
],
"output": null,
}]);
}
exports.defineRowBlock = defineRowBlock;
function defineStatementBlock(name = 'statement_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "%1",
"args0": [
{
"type": "input_statement",
"name": "NAME",
},
],
"previousStatement": null,
"nextStatement": null,
"colour": 230,
"tooltip": "",
"helpUrl": "",
}]);
}
exports.defineStatementBlock = defineStatementBlock;
function defineBasicBlockWithField(name = 'test_field_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "%1",
"args0": [
{
"type": "field_input",
"name": "NAME",
},
],
"output": null,
}]);
}
exports.defineBasicBlockWithField = defineBasicBlockWithField;
function defineMutatorBlocks() {
Blockly.defineBlocksWithJsonArray([
{
'type': 'xml_block',
'mutator': 'xml_mutator',
},
{
'type': 'jso_block',
'mutator': 'jso_mutator',
},
{
'type': 'checkbox_block',
'message0': '%1',
'args0': [
{
'type': 'field_checkbox',
'name': 'CHECK',
},
],
},
]);
const xmlMutator = {
hasInput: false,
mutationToDom: function() {
const mutation = Blockly.utils.xml.createElement('mutation');
mutation.setAttribute('hasInput', this.hasInput);
return mutation;
},
domToMutation: function(mutation) {
this.hasInput = mutation.getAttribute('hasInput') == 'true';
this.updateShape();
},
decompose: function(workspace) {
const topBlock = workspace.newBlock('checkbox_block', 'check_block');
topBlock.initSvg();
topBlock.render();
return topBlock;
},
compose: function(topBlock) {
this.hasInput = topBlock.getFieldValue('CHECK') == 'TRUE';
this.updateShape();
},
updateShape: function() {
if (this.hasInput && !this.getInput('INPUT')) {
this.appendValueInput('INPUT');
} else if (!this.hasInput && this.getInput('INPUT')) {
this.removeInput('INPUT');
}
},
};
Blockly.Extensions.registerMutator('xml_mutator', xmlMutator);
const jsoMutator = {
hasInput: false,
saveExtraState: function() {
return {hasInput: this.hasInput};
},
loadExtraState: function(state) {
this.hasInput = state.hasInput || false;
this.updateShape();
},
decompose: function(workspace) {
const topBlock = workspace.newBlock('checkbox_block', 'check_block');
topBlock.initSvg();
topBlock.render();
return topBlock;
},
compose: function(topBlock) {
this.hasInput = topBlock.getFieldValue('CHECK') == 'TRUE';
this.updateShape();
},
updateShape: function() {
if (this.hasInput && !this.getInput('INPUT')) {
this.appendValueInput('INPUT');
} else if (!this.hasInput && this.getInput('INPUT')) {
this.removeInput('INPUT');
}
},
};
Blockly.Extensions.registerMutator('jso_mutator', jsoMutator);
}
exports.defineMutatorBlocks = defineMutatorBlocks;
function createTestBlock() {
return {
'id': 'test',
'rendered': false,
'workspace': {
'rendered': false,
},
'isShadow': function() {
return false;
},
'renameVarById': Blockly.Block.prototype.renameVarById,
'updateVarName': Blockly.Block.prototype.updateVarName,
};
}
exports.createTestBlock = createTestBlock;
function createRenderedBlock(workspaceSvg, type) {
const block = workspaceSvg.newBlock(type);
block.initSvg();
block.render();
return block;
}
exports.createRenderedBlock = createRenderedBlock;
/**
* Triggers pointer event on target.
* @param {!EventTarget} target The object receiving the event.
* @param {string} type The type of mouse event (eg: mousedown, mouseup,
* click).
* @param {Object<string, string>=} properties Properties to pass into event
* constructor.
*/
function dispatchPointerEvent(target, type, properties) {
const eventInitDict = {
cancelable: true,
bubbles: true,
isPrimary: true,
pressure: 0.5,
clientX: 10,
clientY: 10,
};
if (properties) {
Object.assign(eventInitDict, properties);
}
const event = new PointerEvent(type, eventInitDict);
target.dispatchEvent(event);
}
exports.dispatchPointerEvent = dispatchPointerEvent;
/**
* Creates a key down event used for testing.
* @param {number} keyCode The keycode for the event. Use Blockly.utils.KeyCodes enum.
* @param {!Array<number>=} modifiers A list of modifiers. Use Blockly.utils.KeyCodes enum.
* @return {!KeyboardEvent} The mocked keydown event.
*/
function createKeyDownEvent(keyCode, modifiers) {
const event = {
keyCode: keyCode,
};
if (modifiers && modifiers.length > 0) {
event.altKey = modifiers.indexOf(KeyCodes.ALT) > -1;
event.ctrlKey = modifiers.indexOf(KeyCodes.CTRL) > -1;
event.metaKey = modifiers.indexOf(KeyCodes.META) > -1;
event.shiftKey = modifiers.indexOf(KeyCodes.SHIFT) > -1;
}
return new KeyboardEvent('keydown', event);
}
exports.createKeyDownEvent = createKeyDownEvent;
/**
* Simulates mouse click by triggering relevant mouse events.
* @param {!EventTarget} target The object receiving the event.
* @param {Object<string, string>=} properties Properties to pass into event
* constructor.
*/
function simulateClick(target, properties) {
dispatchPointerEvent(target, 'pointerdown', properties);
dispatchPointerEvent(target, 'pointerup', properties);
dispatchPointerEvent(target, 'click', properties);
}
exports.simulateClick = simulateClick;
@@ -0,0 +1,178 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.blockDefinitions');
export function defineStackBlock(name = 'stack_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "",
"previousStatement": null,
"nextStatement": null,
}]);
}
export function defineRowBlock(name = 'row_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "%1",
"args0": [
{
"type": "input_value",
"name": "INPUT",
},
],
"output": null,
}]);
}
export function defineStatementBlock(name = 'statement_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "%1",
"args0": [
{
"type": "input_statement",
"name": "NAME",
},
],
"previousStatement": null,
"nextStatement": null,
"colour": 230,
"tooltip": "",
"helpUrl": "",
}]);
}
export function defineBasicBlockWithField(name = 'test_field_block') {
Blockly.defineBlocksWithJsonArray([{
"type": name,
"message0": "%1",
"args0": [
{
"type": "field_input",
"name": "NAME",
},
],
"output": null,
}]);
}
export function defineMutatorBlocks() {
Blockly.defineBlocksWithJsonArray([
{
'type': 'xml_block',
'mutator': 'xml_mutator',
},
{
'type': 'jso_block',
'mutator': 'jso_mutator',
},
{
'type': 'checkbox_block',
'message0': '%1',
'args0': [
{
'type': 'field_checkbox',
'name': 'CHECK',
},
],
},
]);
const xmlMutator = {
hasInput: false,
mutationToDom: function() {
const mutation = Blockly.utils.xml.createElement('mutation');
mutation.setAttribute('hasInput', this.hasInput);
return mutation;
},
domToMutation: function(mutation) {
this.hasInput = mutation.getAttribute('hasInput') == 'true';
this.updateShape();
},
decompose: function(workspace) {
const topBlock = workspace.newBlock('checkbox_block', 'check_block');
topBlock.initSvg();
topBlock.render();
return topBlock;
},
compose: function(topBlock) {
this.hasInput = topBlock.getFieldValue('CHECK') == 'TRUE';
this.updateShape();
},
updateShape: function() {
if (this.hasInput && !this.getInput('INPUT')) {
this.appendValueInput('INPUT');
} else if (!this.hasInput && this.getInput('INPUT')) {
this.removeInput('INPUT');
}
},
};
Blockly.Extensions.registerMutator('xml_mutator', xmlMutator);
const jsoMutator = {
hasInput: false,
saveExtraState: function() {
return {hasInput: this.hasInput};
},
loadExtraState: function(state) {
this.hasInput = state.hasInput || false;
this.updateShape();
},
decompose: function(workspace) {
const topBlock = workspace.newBlock('checkbox_block', 'check_block');
topBlock.initSvg();
topBlock.render();
return topBlock;
},
compose: function(topBlock) {
this.hasInput = topBlock.getFieldValue('CHECK') == 'TRUE';
this.updateShape();
},
updateShape: function() {
if (this.hasInput && !this.getInput('INPUT')) {
this.appendValueInput('INPUT');
} else if (!this.hasInput && this.getInput('INPUT')) {
this.removeInput('INPUT');
}
},
};
Blockly.Extensions.registerMutator('jso_mutator', jsoMutator);
}
export function createTestBlock() {
return {
'id': 'test',
'rendered': false,
'workspace': {
'rendered': false,
},
'isShadow': function() {
return false;
},
'renameVarById': Blockly.Block.prototype.renameVarById,
'updateVarName': Blockly.Block.prototype.updateVarName,
};
}
export function createRenderedBlock(workspaceSvg, type) {
const block = workspaceSvg.newBlock(type);
block.initSvg();
block.render();
return block;
}
+115
View File
@@ -0,0 +1,115 @@
/* eslint-disable valid-jsdoc */
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.codeGeneration');
const {runTestSuites} = goog.require('Blockly.test.helpers.common');
/**
* Code generation test case configuration.
* @implements {TestCase}
* @record
*/
export class CodeGenerationTestCase {
/**
* Class for a code generation test case.
*/
constructor() {
/**
* @type {string} The expected code.
*/
this.expectedCode;
/**
* @type {boolean|undefined} Whether to use workspaceToCode instead of
* blockToCode for test.
*/
this.useWorkspaceToCode;
/**
* @type {number|undefined} The expected inner order.
*/
this.expectedInnerOrder;
}
/**
* Creates the block to use for this test case.
* @param {!Blockly.Workspace} workspace The workspace context for this
* test.
* @return {!Blockly.Block} The block to use for the test case.
*/
createBlock(workspace) {}
}
/**
* Code generation test suite.
* @extends {TestSuite<CodeGenerationTestCase, CodeGenerationTestSuite>}
* @record
*/
export class CodeGenerationTestSuite {
/**
* Class for a code generation test suite.
*/
constructor() {
/**
* @type {!Blockly.Generator} The generator to use for running test cases.
*/
this.generator;
}
}
/**
* Returns mocha test callback for code generation based on provided
* generator.
* @param {!Blockly.Generator} generator The generator to use in test.
* @return {function(!CodeGenerationTestCase):!Function} Function that
* returns mocha test callback based on test case.
* @private
*/
const createCodeGenerationTestFn_ = (generator) => {
return (testCase) => {
return function() {
const block = testCase.createBlock(this.workspace);
let code;
let innerOrder;
if (testCase.useWorkspaceToCode) {
code = generator.workspaceToCode(this.workspace);
} else {
generator.init(this.workspace);
code = generator.blockToCode(block);
if (Array.isArray(code)) {
innerOrder = code[1];
code = code[0];
}
}
const assertFunc = (typeof testCase.expectedCode === 'string') ?
chai.assert.equal : chai.assert.match;
assertFunc(code, testCase.expectedCode);
if (!testCase.useWorkspaceToCode &&
testCase.expectedInnerOrder !== undefined) {
chai.assert.equal(innerOrder, testCase.expectedInnerOrder);
}
};
};
};
/**
* Runs blockToCode test suites.
* @param {!Array<!CodeGenerationTestSuite>} testSuites The test suites to run.
*/
export const runCodeGenerationTestSuites = (testSuites) => {
/**
* Creates function used to generate mocha test callback.
* @param {!CodeGenerationTestSuite} suiteInfo The test suite information.
* @return {function(!CodeGenerationTestCase):!Function} Function that
* creates mocha test callback.
*/
const createTestFn = (suiteInfo) => {
return createCodeGenerationTestFn_(suiteInfo.generator);
};
runTestSuites(testSuites, createTestFn);
};
+108
View File
@@ -0,0 +1,108 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.common');
/**
* Test case configuration.
* @record
*/
export class TestCase {
/**
* Class for a test case configuration.
*/
constructor() {
/**
* @type {string} The title for the test case.
*/
this.title;
/**
* @type {boolean|undefined} Whether this test case should be skipped.
* Used to skip buggy test case and should have an associated bug.
*/
this.skip;
/**
* @type {boolean|undefined} Whether this test case should be called as
* only. Used for debugging.
*/
this.only;
}
}
/**
* Test suite configuration.
* @record
* @template {TestCase} T
* @template {TestSuite} U
*/
export class TestSuite {
/**
* Class for a test suite configuration.
*/
constructor() {
/**
* @type {string} The title for the test case.
*/
this.title;
/**
* @type {?Array<T>} The associated test cases.
*/
this.testCases;
/**
* @type {?Array<U>} List of nested inner test suites.
*/
this.testSuites;
/**
* @type {boolean|undefined} Whether this test suite should be skipped.
* Used to skip buggy test case and should have an associated bug.
*/
this.skip;
/**
* @type {boolean|undefined} Whether this test suite should be called as
* only. Used for debugging.
*/
this.only;
}
}
/**
* Runs provided test cases.
* @template {TestCase} T
* @param {!Array<T>} testCases The test cases to run.
* @param {function(T):Function} createTestCallback Creates test
* callback using given test case.
*/
export function runTestCases(testCases, createTestCallback) {
testCases.forEach((testCase) => {
let testCall = (testCase.skip ? test.skip : test);
testCall = (testCase.only ? test.only : testCall);
testCall(testCase.title, createTestCallback(testCase));
});
}
/**
* Runs provided test suite.
* @template {TestCase} T
* @template {TestSuite<T, U>} U
* @param {Array<!U>} testSuites The test suites to run.
* @param {function(!U):(function(T):!Function)
* } createTestCaseCallback Creates test case callback using given test
* suite.
*/
export function runTestSuites(testSuites, createTestCaseCallback) {
testSuites.forEach((testSuite) => {
let suiteCall = (testSuite.skip ? suite.skip : suite);
suiteCall = (testSuite.only ? suite.only : suiteCall);
suiteCall(testSuite.title, function() {
if (testSuite.testSuites && testSuite.testSuites.length) {
runTestSuites(testSuite.testSuites, createTestCaseCallback);
}
if (testSuite.testCases && testSuite.testCases.length) {
runTestCases(testSuite.testCases, createTestCaseCallback(testSuite));
}
});
});
}
+199
View File
@@ -0,0 +1,199 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.events');
/**
* Creates spy for workspace fireChangeListener
* @param {!Blockly.Workspace} workspace The workspace to spy fireChangeListener
* calls on.
* @return {!SinonSpy} The created spy.
*/
export function createFireChangeListenerSpy(workspace) {
return sinon.spy(workspace, 'fireChangeListener');
}
/**
* Asserts whether the given xml property has the expected property.
* @param {!Node} xmlValue The xml value to check.
* @param {!Node|string} expectedValue The expected value.
* @param {string=} message Optional message to use in assert message.
* @private
*/
function assertXmlPropertyEqual_(xmlValue, expectedValue, message) {
const value = Blockly.Xml.domToText(xmlValue);
if (expectedValue instanceof Node) {
expectedValue = Blockly.Xml.domToText(expectedValue);
}
chai.assert.equal(value, expectedValue, message);
}
/**
* Asserts that the given object has the expected xml properties.
* @param {Object} obj The object to check.
* @param {Object<string, Node|string>} expectedXmlProperties The expected xml
* properties.
* @private
*/
function assertXmlProperties_(obj, expectedXmlProperties) {
Object.keys(expectedXmlProperties).map((key) => {
const value = obj[key];
const expectedValue = expectedXmlProperties[key];
if (expectedValue === undefined) {
chai.assert.isUndefined(value,
'Expected ' + key + ' property to be undefined');
return;
}
chai.assert.exists(value, 'Expected ' + key + ' property to exist');
assertXmlPropertyEqual_(value, expectedValue, 'Checking property ' + key);
});
}
/**
* Whether given key indicates that the property is xml.
* @param {string} key The key to check.
* @return {boolean} Whether the given key is for xml property.
* @private
*/
function isXmlProperty_(key) {
return key.toLowerCase().endsWith('xml');
}
/**
* Asserts that the given event has the expected values.
* @param {!Blockly.Events.Abstract} event The event to check.
* @param {string} expectedType Expected type of event fired.
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string} expectedBlockId Expected block id of event fired.
* @param {!Object<string, *>} expectedProperties Map of of additional expected
* properties to check on fired event.
* @param {boolean=} [isUiEvent=false] Whether the event is a UI event.
* @param {string=} message Optional message to prepend assert messages.
*/
export function assertEventEquals(event, expectedType,
expectedWorkspaceId, expectedBlockId, expectedProperties, isUiEvent = false, message) {
let prependMessage = message ? message + ' ' : '';
prependMessage += 'Event fired ';
chai.assert.equal(event.type, expectedType,
prependMessage + 'type');
chai.assert.equal(event.workspaceId, expectedWorkspaceId,
prependMessage + 'workspace id');
chai.assert.equal(event.blockId, expectedBlockId,
prependMessage + 'block id');
Object.keys(expectedProperties).map((key) => {
const value = event[key];
const expectedValue = expectedProperties[key];
if (expectedValue === undefined) {
chai.assert.isUndefined(value, prependMessage + key);
return;
}
chai.assert.exists(value, prependMessage + key);
if (isXmlProperty_(key)) {
assertXmlPropertyEqual_(value, expectedValue,
prependMessage + key);
} else {
chai.assert.equal(value, expectedValue,
prependMessage + key);
}
});
if (isUiEvent) {
chai.assert.isTrue(event.isUiEvent);
} else {
chai.assert.isFalse(event.isUiEvent);
}
}
/**
* Asserts that an event with the given values was fired.
* @param {!SinonSpy|!SinonSpyCall} spy The spy or spy call to use.
* @param {function(new:Blockly.Events.Abstract)} instanceType Expected instance
* type of event fired.
* @param {!Object<string, *>} expectedProperties Map of of expected properties
* to check on fired event.
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string=} expectedBlockId Expected block id of event fired.
*/
export function assertEventFired(spy, instanceType, expectedProperties,
expectedWorkspaceId, expectedBlockId) {
expectedProperties = Object.assign({
workspaceId: expectedWorkspaceId,
blockId: expectedBlockId,
}, expectedProperties);
const expectedEvent =
sinon.match.instanceOf(instanceType).and(sinon.match(expectedProperties));
sinon.assert.calledWith(spy, expectedEvent);
}
/**
* Asserts that an event with the given values was not fired.
* @param {!SpyCall} spy The spy to use.
* @param {function(new:Blockly.Events.Abstract)} instanceType Expected instance
* type of event fired.
* @param {!Object<string, *>} expectedProperties Map of of expected properties
* to check on fired event.
* @param {string=} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string=} expectedBlockId Expected block id of event fired.
*/
export function assertEventNotFired(spy, instanceType, expectedProperties,
expectedWorkspaceId, expectedBlockId) {
expectedProperties.type = instanceType.prototype.type;
if (expectedWorkspaceId !== undefined) {
expectedProperties.workspaceId = expectedWorkspaceId;
}
if (expectedBlockId !== undefined) {
expectedProperties.blockId = expectedBlockId;
}
const expectedEvent =
sinon.match.instanceOf(instanceType).and(sinon.match(expectedProperties));
sinon.assert.neverCalledWith(spy, expectedEvent);
}
/**
* Filters out xml properties from given object based on key.
* @param {Object<string, *>} properties The properties to filter.
* @return {Array<Object<string, *>>} A list containing split non
* xml properties and xml properties. [Object<string, *>, Object<string, *>]
* @private
*/
function splitByXmlProperties_(properties) {
const xmlProperties = {};
const nonXmlProperties = {};
Object.keys(properties).forEach((key) => {
if (isXmlProperty_(key)) {
xmlProperties[key] = properties[key];
return false;
} else {
nonXmlProperties[key] = properties[key];
}
});
return [nonXmlProperties, xmlProperties];
}
/**
* Asserts that the event passed to the nth call of the given spy has the
* expected values. Assumes that the event is passed as the first argument.
* @param {!SinonSpy} spy The spy to use.
* @param {number} n Which call to check.
* @param {function(new:Blockly.Events.Abstract)} instanceType Expected instance
* type of event fired.
* @param {Object<string, *>} expectedProperties Map of of expected properties
* to check on fired event.
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
* @param {?string=} expectedBlockId Expected block id of event fired.
*/
export function assertNthCallEventArgEquals(spy, n, instanceType, expectedProperties,
expectedWorkspaceId, expectedBlockId) {
const nthCall = spy.getCall(n);
const splitProperties = splitByXmlProperties_(expectedProperties);
const nonXmlProperties = splitProperties[0];
const xmlProperties = splitProperties[1];
assertEventFired(nthCall, instanceType, nonXmlProperties, expectedWorkspaceId,
expectedBlockId);
const eventArg = nthCall.firstArg;
assertXmlProperties_(eventArg, xmlProperties);
}
+276
View File
@@ -0,0 +1,276 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.fields');
const {runTestCases, TestCase} = goog.require('Blockly.test.helpers.common');
/**
* Field value test case.
* @implements {TestCase}
* @record
*/
export class FieldValueTestCase {
/**
* Class for a a field value test case.
*/
constructor() {
/**
* @type {*} The value to use in test.
*/
this.value;
/**
* @type {*} The expected value.
*/
this.expectedValue;
/**
* @type {string|undefined} The expected text value. Provided if different
* from String(expectedValue).
*/
this.expectedText;
/**
* @type {!RegExp|string|undefined} The optional error message matcher.
* Provided if test case is expected to throw.
*/
this.errMsgMatcher;
}
}
/**
* Field creation test case.
* @extends {FieldValueTestCase}
* @record
*/
export class FieldCreationTestCase {
/**
* Class for a field creation test case.
*/
constructor() {
/**
* @type {Array<*>} The arguments to pass to field constructor.
*/
this.args;
/**
* @type {string} The json to use in field creation.
*/
this.json;
}
}
/**
* Assert a field's value is the same as the expected value.
* @param {!Blockly.Field} field The field.
* @param {*} expectedValue The expected value.
* @param {string=} expectedText The expected text.
*/
export function assertFieldValue(field, expectedValue, expectedText = undefined) {
const actualValue = field.getValue();
const actualText = field.getText();
if (expectedText === undefined) {
expectedText = String(expectedValue);
}
chai.assert.equal(actualValue, expectedValue, 'Value');
chai.assert.equal(actualText, expectedText, 'Text');
}
/**
* Runs provided creation test cases.
* @param {!Array<!FieldCreationTestCase>} testCases The test cases to run.
* @param {function(!Blockly.Field, !FieldCreationTestCase)} assertion The
* assertion to use.
* @param {function(new:Blockly.Field,!FieldCreationTestCase):Blockly.Field
* } creation A function that returns an instance of the field based on the
* provided test case.
* @private
*/
function runCreationTests_(testCases, assertion, creation) {
/**
* Creates test callback for creation test.
* @param {FieldCreationTestCase} testCase The test case to use.
* @return {Function} The test callback.
*/
const createTestFn = (testCase) => {
return function() {
const field = creation.call(this, testCase);
assertion(field, testCase);
};
};
runTestCases(testCases, createTestFn);
}
/**
* Runs provided creation test cases.
* @param {!Array<!FieldCreationTestCase>} testCases The test cases to run.
* @param {function(new:Blockly.Field,!FieldCreationTestCase):Blockly.Field
* } creation A function that returns an instance of the field based on the
* provided test case.
* @private
*/
function runCreationTestsAssertThrows_(testCases, creation) {
/**
* Creates test callback for creation test.
* @param {!FieldCreationTestCase} testCase The test case to use.
* @return {!Function} The test callback.
*/
const createTestFn = (testCase) => {
return function() {
chai.assert.throws(function() {
creation.call(this, testCase);
}, testCase.errMsgMatcher);
};
};
runTestCases(testCases, createTestFn);
}
/**
* Runs suite of tests for constructor for the specified field.
* @param {function(new:Blockly.Field, *=)} TestedField The class of the field
* being tested.
* @param {Array<!FieldCreationTestCase>} validValueTestCases Test cases with
* valid values for given field.
* @param {Array<!FieldCreationTestCase>} invalidValueTestCases Test cases with
* invalid values for given field.
* @param {function(!Blockly.Field, !FieldCreationTestCase)
* } validRunAssertField Asserts that field has expected values.
* @param {function(!Blockly.Field)=} assertFieldDefault Asserts that field has
* default values. If undefined, tests will check that field throws when
* invalid value is passed rather than asserting default.
* @param {function(!FieldCreationTestCase=)=} customCreateWithJs Custom
* creation function to use in tests.
*/
export function runConstructorSuiteTests(TestedField, validValueTestCases,
invalidValueTestCases, validRunAssertField, assertFieldDefault,
customCreateWithJs) {
suite('Constructor', function() {
if (assertFieldDefault) {
test('Empty', function() {
const field = customCreateWithJs ? customCreateWithJs.call(this) :
new TestedField();
assertFieldDefault(field);
});
} else {
test('Empty', function() {
chai.assert.throws(function() {
customCreateWithJs ? customCreateWithJs.call(this) :
new TestedField();
});
});
}
/**
* Creates a field using its constructor and the provided test case.
* @param {!FieldCreationTestCase} testCase The test case information.
* @return {!Blockly.Field} The instantiated field.
*/
const createWithJs = function(testCase) {
return customCreateWithJs ? customCreateWithJs.call(this, testCase) :
new TestedField(...testCase.args);
};
if (assertFieldDefault) {
runCreationTests_(
invalidValueTestCases, assertFieldDefault, createWithJs);
} else {
runCreationTestsAssertThrows_(invalidValueTestCases, createWithJs);
}
runCreationTests_(validValueTestCases, validRunAssertField, createWithJs);
});
}
/**
* Runs suite of tests for fromJson creation of specified field.
* @param {function(new:Blockly.Field, *=)} TestedField The class of the field
* being tested.
* @param {!Array<!FieldCreationTestCase>} validValueTestCases Test cases with
* valid values for given field.
* @param {!Array<!FieldCreationTestCase>} invalidValueTestCases Test cases with
* invalid values for given field.
* @param {function(!Blockly.Field, !FieldValueTestCase)
* } validRunAssertField Asserts that field has expected values.
* @param {function(!Blockly.Field)=} assertFieldDefault Asserts that field has
* default values. If undefined, tests will check that field throws when
* invalid value is passed rather than asserting default.
* @param {function(!FieldCreationTestCase=)=} customCreateWithJson Custom
* creation function to use in tests.
*/
export function runFromJsonSuiteTests(TestedField, validValueTestCases,
invalidValueTestCases, validRunAssertField, assertFieldDefault,
customCreateWithJson) {
suite('fromJson', function() {
if (assertFieldDefault) {
test('Empty', function() {
const field = customCreateWithJson ? customCreateWithJson.call(this) :
TestedField.fromJson({});
assertFieldDefault(field);
});
} else {
test('Empty', function() {
chai.assert.throws(function() {
customCreateWithJson ? customCreateWithJson.call(this) :
TestedField.fromJson({});
});
});
}
/**
* Creates a field using fromJson and the provided test case.
* @param {!FieldCreationTestCase} testCase The test case information.
* @return {!Blockly.Field} The instantiated field.
*/
const createWithJson = function(testCase) {
return customCreateWithJson ? customCreateWithJson.call(this, testCase) :
TestedField.fromJson(testCase.json);
};
if (assertFieldDefault) {
runCreationTests_(
invalidValueTestCases, assertFieldDefault, createWithJson);
} else {
runCreationTestsAssertThrows_(invalidValueTestCases, createWithJson);
}
runCreationTests_(validValueTestCases, validRunAssertField, createWithJson);
});
}
/**
* Runs tests for setValue calls.
* @param {!Array<!FieldValueTestCase>} validValueTestCases Test cases with
* valid values.
* @param {!Array<!FieldValueTestCase>} invalidValueTestCases Test cases with
* invalid values.
* @param {*} invalidRunExpectedValue Expected value for field after invalid
* call to setValue.
* @param {string=} invalidRunExpectedText Expected text for field after invalid
* call to setValue.
*/
export function runSetValueTests(validValueTestCases, invalidValueTestCases,
invalidRunExpectedValue, invalidRunExpectedText) {
/**
* Creates test callback for invalid setValue test.
* @param {!FieldValueTestCase} testCase The test case information.
* @return {!Function} The test callback.
*/
const createInvalidSetValueTestCallback = (testCase) => {
return function() {
this.field.setValue(testCase.value);
assertFieldValue(
this.field, invalidRunExpectedValue, invalidRunExpectedText);
};
};
/**
* Creates test callback for valid setValue test.
* @param {!FieldValueTestCase} testCase The test case information.
* @return {!Function} The test callback.
*/
const createValidSetValueTestCallback = (testCase) => {
return function() {
this.field.setValue(testCase.value);
assertFieldValue(
this.field, testCase.expectedValue, testCase.expectedText);
};
};
runTestCases(invalidValueTestCases, createInvalidSetValueTestCallback);
runTestCases(validValueTestCases, createValidSetValueTestCallback);
}
@@ -3,7 +3,7 @@
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.module('Blockly.test.procedureHelpers');
goog.declareModuleId('Blockly.test.helpers.procedures');
const {ConnectionType} = goog.require('Blockly.ConnectionType');
@@ -55,7 +55,7 @@ function assertCallBlockArgsStructure(callBlock, args) {
* @param {boolean=} hasStatements If we expect the procedure def to have a
* statement input or not.
*/
function assertDefBlockStructure(defBlock, hasReturn = false,
export function assertDefBlockStructure(defBlock, hasReturn = false,
args = [], varIds = [], hasStatements = true) {
if (hasStatements) {
chai.assert.isNotNull(defBlock.getInput('STACK'),
@@ -82,7 +82,6 @@ function assertDefBlockStructure(defBlock, hasReturn = false,
chai.assert.sameOrderedMembers(defBlock.getVars(), args);
assertBlockVarModels(defBlock, varIds);
}
exports.assertDefBlockStructure = assertDefBlockStructure;
/**
* Asserts that the procedure definition block has the expected inputs and
@@ -91,7 +90,7 @@ exports.assertDefBlockStructure = assertDefBlockStructure;
* @param {Array<string>=} args An array of argument names.
* @param {Array<string>=} varIds An array of variable ids.
*/
function assertCallBlockStructure(callBlock, args = [], varIds = []) {
export function assertCallBlockStructure(callBlock, args = [], varIds = []) {
if (args.length) {
chai.assert.include(callBlock.toString(), 'with');
} else {
@@ -101,7 +100,6 @@ function assertCallBlockStructure(callBlock, args = [], varIds = []) {
assertCallBlockArgsStructure(callBlock, args);
assertBlockVarModels(callBlock, varIds);
}
exports.assertCallBlockStructure = assertCallBlockStructure;
/**
* Creates procedure definition block using domToBlock call.
@@ -111,7 +109,7 @@ exports.assertCallBlockStructure = assertCallBlockStructure;
* @param {Array<string>=} args An array of argument names.
* @return {Blockly.Block} The created block.
*/
function createProcDefBlock(
export function createProcDefBlock(
workspace, hasReturn = false, args = []) {
const type = hasReturn ?
'procedures_defreturn' : 'procedures_defnoreturn';
@@ -125,7 +123,6 @@ function createProcDefBlock(
'</block>';
return Blockly.Xml.domToBlock(Blockly.Xml.textToDom(xml), workspace);
}
exports.createProcDefBlock = createProcDefBlock;
/**
* Creates procedure call block using domToBlock call.
@@ -134,7 +131,7 @@ exports.createProcDefBlock = createProcDefBlock;
* has return.
* @return {Blockly.Block} The created block.
*/
function createProcCallBlock(
export function createProcCallBlock(
workspace, hasReturn = false) {
const type = hasReturn ?
'procedures_callreturn' : 'procedures_callnoreturn';
@@ -144,4 +141,3 @@ function createProcCallBlock(
'</block>'
), workspace);
}
exports.createProcCallBlock = createProcCallBlock;
+130
View File
@@ -0,0 +1,130 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.serialization');
const {runTestCases} = goog.require('Blockly.test.helpers.common');
/**
* Serialization test case.
* @implements {TestCase}
* @record
*/
export class SerializationTestCase {
/**
* Class for a block serialization test case.
*/
constructor() {
/**
* @type {string} The block xml to use for test. Do not provide if json is
* provided.
*/
this.xml;
/**
* @type {string|undefined} The expected xml after round trip. Provided if
* it different from xml that was passed in.
*/
this.expectedXml;
/**
* @type {string} The block json to use for test. Do not provide if xml is
* provided.
*/
this.json;
/**
* @type {string|undefined} The expected json after round trip. Provided if
* it is different from json that was passed in.
*/
this.expectedJson;
}
/**
* Asserts that the block created from xml has the expected structure.
* @param {!Blockly.Block} block The block to check.
*/
assertBlockStructure(block) {}
}
/**
* Runs serialization test suite.
* @param {!Array<!SerializationTestCase>} testCases The test cases to run.
*/
export const runSerializationTestSuite = (testCases) => {
/**
* Creates test callback for xmlToBlock test.
* @param {!SerializationTestCase} testCase The test case information.
* @return {!Function} The test callback.
*/
const createSerializedDataToBlockTestCallback = (testCase) => {
return function() {
let block;
if (testCase.json) {
block = Blockly.serialization.blocks.append(
testCase.json, this.workspace);
} else {
block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
testCase.xml), this.workspace);
}
testCase.assertBlockStructure(block);
};
};
/**
* Creates test callback for xml round trip test.
* @param {!SerializationTestCase} testCase The test case information.
* @return {!Function} The test callback.
*/
const createRoundTripTestCallback = (testCase) => {
return function() {
if (testCase.json) {
const block = Blockly.serialization.blocks.append(
testCase.json, this.workspace);
const generatedJson = Blockly.serialization.blocks.save(block);
const expectedJson = testCase.expectedJson || testCase.json;
chai.assert.deepEqual(generatedJson, expectedJson);
} else {
const block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
testCase.xml), this.workspace);
const generatedXml =
Blockly.Xml.domToPrettyText(
Blockly.Xml.blockToDom(block));
const expectedXml = testCase.expectedXml || testCase.xml;
chai.assert.equal(generatedXml, expectedXml);
}
};
};
suite('Serialization', function() {
suite('xmlToBlock', function() {
runTestCases(testCases, createSerializedDataToBlockTestCallback);
});
suite('xml round-trip', function() {
setup(function() {
// The genUid is undergoing change as part of the 2021Q3
// goog.module migration:
//
// - It is being moved from Blockly.utils to
// Blockly.utils.idGenerator (which itself is being renamed
// from IdGenerator).
// - For compatibility with changes to the module system (from
// goog.provide to goog.module and in future to ES modules),
// .genUid is now a wrapper around .TEST_ONLY.genUid, which
// can be safely stubbed by sinon or other similar
// frameworks in a way that will continue to work.
if (Blockly.utils.idGenerator &&
Blockly.utils.idGenerator.TEST_ONLY) {
sinon.stub(Blockly.utils.idGenerator.TEST_ONLY, 'genUid')
.returns('1');
} else {
// Fall back to stubbing original version on Blockly.utils.
sinon.stub(Blockly.utils, 'genUid').returns('1');
}
});
teardown(function() {
sinon.restore();
});
runTestCases(testCases, createRoundTripTestCallback);
});
});
};
+202
View File
@@ -0,0 +1,202 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.setupTeardown');
const eventUtils = goog.require('Blockly.Events.utils');
const {Blocks} = goog.require('Blockly.blocks');
/**
* Safely disposes of Blockly workspace, logging any errors.
* Assumes that sharedTestSetup has also been called. This should be called
* using workspaceTeardown.call(this).
* @param {!Blockly.Workspace} workspace The workspace to dispose.
*/
export function workspaceTeardown(workspace) {
try {
this.clock.runAll(); // Run all queued setTimeout calls.
workspace.dispose();
this.clock.runAll(); // Run all remaining queued setTimeout calls.
} catch (e) {
const testRef = this.currentTest || this.test;
console.error(testRef.fullTitle() + '\n', e);
}
}
/**
* Creates stub for Blockly.Events.fire that advances the clock forward after
* the event fires so it is processed immediately instead of on a timeout.
* @param {!SinonClock} clock The sinon clock.
* @return {!SinonStub} The created stub.
* @private
*/
function createEventsFireStubFireImmediately_(clock) {
const stub = sinon.stub(eventUtils, 'fire');
stub.callsFake(function(event) {
// Call original method.
stub.wrappedMethod.call(this, ...arguments);
// Advance clock forward to run any queued events.
clock.runAll();
});
return stub;
}
/**
* Adds message to shared cleanup object so that it is cleaned from
* Blockly.Messages global in sharedTestTeardown.
* @param {!Object} sharedCleanupObj The shared cleanup object created in
* sharedTestSetup.
* @param {string} message The message to add to shared cleanup object.
*/
export function addMessageToCleanup(sharedCleanupObj, message) {
sharedCleanupObj.messagesCleanup_.push(message);
}
/**
* Adds block type to shared cleanup object so that it is cleaned from
* Blockly.Blocks global in sharedTestTeardown.
* @param {!Object} sharedCleanupObj The shared cleanup object created in
* sharedTestSetup.
* @param {string} blockType The block type to add to shared cleanup object.
*/
export function addBlockTypeToCleanup(sharedCleanupObj, blockType) {
sharedCleanupObj.blockTypesCleanup_.push(blockType);
}
/**
* Wraps Blockly.defineBlocksWithJsonArray using stub in order to keep track of
* block types passed in to method on shared cleanup object so they are cleaned
* from Blockly.Blocks global in sharedTestTeardown.
* @param {!Object} sharedCleanupObj The shared cleanup object created in
* sharedTestSetup.
* @private
*/
function wrapDefineBlocksWithJsonArrayWithCleanup_(sharedCleanupObj) {
const stub = sinon.stub(Blockly, 'defineBlocksWithJsonArray');
stub.callsFake(function(jsonArray) {
if (jsonArray) {
jsonArray.forEach((jsonBlock) => {
if (jsonBlock) {
addBlockTypeToCleanup(sharedCleanupObj, jsonBlock['type']);
}
});
}
// Calls original method.
stub.wrappedMethod.call(this, ...arguments);
});
}
/**
* Shared setup method that sets up fake timer for clock so that pending
* setTimeout calls can be cleared in test teardown along with other common
* stubs. Should be called in setup of outermost suite using
* sharedTestSetup.call(this).
* The sinon fake timer defined on this.clock_ should not be reset in tests to
* avoid causing issues with cleanup in sharedTestTeardown.
*
* Stubs created in this setup (unless disabled by options passed):
* - Blockly.Events.fire - this.eventsFireStub - wraps fire event to trigger
* fireNow_ call immediately, rather than on timeout
* - Blockly.defineBlocksWithJsonArray - thin wrapper that adds logic to keep
* track of block types defined so that they can be undefined in
* sharedTestTeardown and calls original method.
*
* @param {Object<string, boolean>} options Options to enable/disable setup
* of certain stubs.
*/
export function sharedTestSetup(options = {}) {
this.sharedSetupCalled_ = true;
// Sandbox created for greater control when certain stubs are cleared.
this.sharedSetupSandbox_ = sinon.createSandbox();
this.clock = this.sharedSetupSandbox_.useFakeTimers();
if (options['fireEventsNow'] === undefined || options['fireEventsNow']) {
// Stubs event firing unless passed option "fireEventsNow: false"
this.eventsFireStub = createEventsFireStubFireImmediately_(this.clock);
}
this.sharedCleanup = {
blockTypesCleanup_: [],
messagesCleanup_: [],
};
this.blockTypesCleanup_ = this.sharedCleanup.blockTypesCleanup_;
this.messagesCleanup_ = this.sharedCleanup.messagesCleanup_;
wrapDefineBlocksWithJsonArrayWithCleanup_(this.sharedCleanup);
}
/**
* Shared cleanup method that clears up pending setTimeout calls, disposes of
* workspace, and resets global variables. Should be called in setup of
* outermost suite using sharedTestTeardown.call(this).
*/
export function sharedTestTeardown() {
const testRef = this.currentTest || this.test;
if (!this.sharedSetupCalled_) {
console.error('"' + testRef.fullTitle() + '" did not call sharedTestSetup');
}
try {
if (this.workspace) {
workspaceTeardown.call(this, this.workspace);
this.workspace = null;
} else {
this.clock.runAll(); // Run all queued setTimeout calls.
}
} catch (e) {
console.error(testRef.fullTitle() + '\n', e);
} finally {
// Clear Blockly.Event state.
eventUtils.setGroup(false);
while (!eventUtils.isEnabled()) {
eventUtils.enable();
}
eventUtils.setRecordUndo(true);
if (eventUtils.TEST_ONLY.FIRE_QUEUE.length) {
// If this happens, it may mean that some previous test is missing cleanup
// (i.e. a previous test added an event to the queue on a timeout that
// did not use a stubbed clock).
eventUtils.TEST_ONLY.FIRE_QUEUE.length = 0;
console.warn('"' + testRef.fullTitle() +
'" needed cleanup of Blockly.Events.TEST_ONLY.FIRE_QUEUE. This may ' +
'indicate leakage from an earlier test');
}
// Restore all stubbed methods.
this.sharedSetupSandbox_.restore();
sinon.restore();
const blockTypes = this.sharedCleanup.blockTypesCleanup_;
for (let i = 0; i < blockTypes.length; i++) {
delete Blocks[blockTypes[i]];
}
const messages = this.sharedCleanup.messagesCleanup_;
for (let i = 0; i < messages.length; i++) {
delete Blockly.Msg[messages[i]];
}
Blockly.WidgetDiv.testOnly_setDiv(null);
}
}
/**
* Creates stub for Blockly.utils.genUid that returns the provided id or ids.
* Recommended to also assert that the stub is called the expected number of
* times.
* @param {string|!Array<string>} returnIds The return values to use for the
* created stub. If a single value is passed, then the stub always returns
* that value.
* @return {!SinonStub} The created stub.
*/
export function createGenUidStubWithReturns(returnIds) {
const stub = sinon.stub(Blockly.utils.idGenerator.TEST_ONLY, "genUid");
if (Array.isArray(returnIds)) {
for (let i = 0; i < returnIds.length; i++) {
stub.onCall(i).returns(returnIds[i]);
}
} else {
stub.returns(returnIds);
}
return stub;
}
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
goog.module('Blockly.test.toolboxHelpers');
goog.declareModuleId('Blockly.test.helpers.toolboxDefinitions');
/**
@@ -12,7 +12,7 @@ goog.module('Blockly.test.toolboxHelpers');
* @return {Blockly.utils.toolbox.ToolboxJson} The array holding information
* for a toolbox.
*/
function getCategoryJSON() {
export function getCategoryJSON() {
return {"contents": [
{
"kind": "CATEGORY",
@@ -42,14 +42,13 @@ function getCategoryJSON() {
"name": "Second",
}]};
}
exports.getCategoryJSON = getCategoryJSON;
/**
* Get JSON for a simple toolbox.
* @return {Blockly.utils.toolbox.ToolboxJson} The array holding information
* for a simple toolbox.
*/
function getSimpleJson() {
export function getSimpleJson() {
return {"contents": [
{
"kind": "BLOCK",
@@ -83,9 +82,8 @@ function getSimpleJson() {
},
]};
}
exports.getSimpleJson = getSimpleJson;
function getProperSimpleJson() {
export function getProperSimpleJson() {
return {
"contents": [
{
@@ -128,14 +126,13 @@ function getProperSimpleJson() {
},
]};
}
exports.getProperSimpleJson = getProperSimpleJson;
/**
* Get JSON for a toolbox that contains categories that contain categories.
* @return {Blockly.utils.toolbox.ToolboxJson} The array holding information
* for a toolbox.
*/
function getDeeplyNestedJSON() {
export function getDeeplyNestedJSON() {
return {"contents": [
{
"kind": "CATEGORY",
@@ -173,13 +170,12 @@ function getDeeplyNestedJSON() {
"name": "Second",
}]};
}
exports.getDeeplyNestedJSON = getDeeplyNestedJSON;
/**
* Get an array filled with xml elements.
* @return {Array<Node>} Array holding xml elements for a toolbox.
*/
function getXmlArray() {
export function getXmlArray() {
const block = Blockly.Xml.textToDom(
`<block type="logic_compare">
<field name="OP">NEQ</field>
@@ -199,9 +195,8 @@ function getXmlArray() {
const label = Blockly.Xml.textToDom('<label text="tooltips"></label>');
return [block, separator, button, label];
}
exports.getXmlArray = getXmlArray;
function getInjectedToolbox() {
export function getInjectedToolbox() {
/**
* Category: First
* sep
@@ -221,18 +216,16 @@ function getInjectedToolbox() {
});
return workspace.getToolbox();
}
exports.getInjectedToolbox = getInjectedToolbox;
function getBasicToolbox() {
export function getBasicToolbox() {
const workspace = new Blockly.WorkspaceSvg(new Blockly.Options({}));
const toolbox = new Blockly.Toolbox(workspace);
toolbox.HtmlDiv = document.createElement('div');
toolbox.flyout_ = sinon.createStubInstance(Blockly.VerticalFlyout);
return toolbox;
}
exports.getBasicToolbox = getBasicToolbox;
function getCollapsibleItem(toolbox) {
export function getCollapsibleItem(toolbox) {
const contents = toolbox.contents_;
for (let i = 0; i < contents.length; i++) {
const item = contents[i];
@@ -241,9 +234,8 @@ function getCollapsibleItem(toolbox) {
}
}
}
exports.getCollapsibleItem = getCollapsibleItem;
function getNonCollapsibleItem(toolbox) {
export function getNonCollapsibleItem(toolbox) {
const contents = toolbox.contents_;
for (let i = 0; i < contents.length; i++) {
const item = contents[i];
@@ -252,14 +244,11 @@ function getNonCollapsibleItem(toolbox) {
}
}
}
exports.getNonCollapsibleItem = getNonCollapsibleItem;
function getChildItem(toolbox) {
export function getChildItem(toolbox) {
return toolbox.getToolboxItemById('nestedCategory');
}
exports.getChildItem = getChildItem;
function getSeparator(toolbox) {
export function getSeparator(toolbox) {
return toolbox.getToolboxItemById('separator');
}
exports.getSeparator = getSeparator;
+65
View File
@@ -0,0 +1,65 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.userInput');
const {KeyCodes} = goog.require('Blockly.utils.KeyCodes');
/**
* Triggers pointer event on target.
* @param {!EventTarget} target The object receiving the event.
* @param {string} type The type of mouse event (eg: mousedown, mouseup,
* click).
* @param {Object<string, string>=} properties Properties to pass into event
* constructor.
*/
export function dispatchPointerEvent(target, type, properties) {
const eventInitDict = {
cancelable: true,
bubbles: true,
isPrimary: true,
pressure: 0.5,
clientX: 10,
clientY: 10,
};
if (properties) {
Object.assign(eventInitDict, properties);
}
const event = new PointerEvent(type, eventInitDict);
target.dispatchEvent(event);
}
/**
* Creates a key down event used for testing.
* @param {number} keyCode The keycode for the event. Use Blockly.utils.KeyCodes enum.
* @param {!Array<number>=} modifiers A list of modifiers. Use Blockly.utils.KeyCodes enum.
* @return {!KeyboardEvent} The mocked keydown event.
*/
export function createKeyDownEvent(keyCode, modifiers) {
const event = {
keyCode: keyCode,
};
if (modifiers && modifiers.length > 0) {
event.altKey = modifiers.indexOf(KeyCodes.ALT) > -1;
event.ctrlKey = modifiers.indexOf(KeyCodes.CTRL) > -1;
event.metaKey = modifiers.indexOf(KeyCodes.META) > -1;
event.shiftKey = modifiers.indexOf(KeyCodes.SHIFT) > -1;
}
return new KeyboardEvent('keydown', event);
}
/**
* Simulates mouse click by triggering relevant mouse events.
* @param {!EventTarget} target The object receiving the event.
* @param {Object<string, string>=} properties Properties to pass into event
* constructor.
*/
export function simulateClick(target, properties) {
dispatchPointerEvent(target, 'pointerdown', properties);
dispatchPointerEvent(target, 'pointerup', properties);
dispatchPointerEvent(target, 'click', properties);
}
+24
View File
@@ -0,0 +1,24 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.variables');
/**
* Check if a variable with the given values exists.
* @param {Blockly.Workspace|Blockly.VariableMap} container The workspace or
* variableMap the checked variable belongs to.
* @param {!string} name The expected name of the variable.
* @param {!string} type The expected type of the variable.
* @param {!string} id The expected id of the variable.
*/
export function assertVariableValues(container, name, type, id) {
const variable = container.getVariableById(id);
chai.assert.isDefined(variable);
chai.assert.equal(variable.name, name);
chai.assert.equal(variable.type, type);
chai.assert.equal(variable.getId(), id);
}
+84
View File
@@ -0,0 +1,84 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.helpers.warnings');
/**
* Captures the strings sent to console.warn() when calling a function.
* Copies from core.
* @param {Function} innerFunc The function where warnings may called.
* @return {Array<string>} The warning messages (only the first arguments).
*/
export function captureWarnings(innerFunc) {
const msgs = [];
const nativeConsoleWarn = console.warn;
try {
console.warn = function(msg) {
msgs.push(msg);
};
innerFunc();
} finally {
console.warn = nativeConsoleWarn;
}
return msgs;
}
/**
* Asserts that the given function logs the provided warning messages.
* @param {function()} innerFunc The function to call.
* @param {Array<!RegExp>|!RegExp} messages A list of regex for the expected
* messages (in the expected order).
*/
export function assertWarnings(innerFunc, messages) {
if (!Array.isArray(messages)) {
messages = [messages];
}
const warnings = captureWarnings(innerFunc);
chai.assert.lengthOf(warnings, messages.length);
messages.forEach((message, i) => {
chai.assert.match(warnings[i], message);
});
}
/**
* Asserts that the given function logs no warning messages.
* @param {function()} innerFunc The function to call.
*/
export function assertNoWarnings(innerFunc) {
assertWarnings(innerFunc, []);
}
/**
* Stubs Blockly.utils.deprecation.warn call.
* @return {!SinonStub} The created stub.
*/
export function createDeprecationWarningStub() {
return sinon.stub(Blockly.utils.deprecation, 'warn');
}
/**
* Asserts whether the given deprecation warning stub or call was called with
* the expected functionName.
* @param {!SinonSpy|!SinonSpyCall} spyOrSpyCall The spy or spy call to use.
* @param {string} functionName The function name to check that the given spy or
* spy call was called with.
*/
export function assertDeprecationWarningCall(spyOrSpyCall, functionName) {
sinon.assert.calledWith(spyOrSpyCall, functionName);
}
/**
* Asserts that there was a single deprecation warning call with the given
* functionName passed.
* @param {!SinonSpy} spy The spy to use.
* @param {string} functionName The function name to check that the given spy
* was called with.
*/
export function assertSingleDeprecationWarningCall(spy, functionName) {
sinon.assert.calledOnce(spy);
assertDeprecationWarningCall(spy.getCall(0), functionName);
}
@@ -4,13 +4,15 @@
* SPDX-License-Identifier: Apache-2.0
*/
goog.module('Blockly.test.workspaceHelpers');
goog.declareModuleId('Blockly.test.helpers.workspace');
const {assertVariableValues, assertWarnings, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {assertVariableValues} = goog.require('Blockly.test.helpers.variables');
const {assertWarnings} = goog.require('Blockly.test.helpers.warnings');
const eventUtils = goog.require('Blockly.Events.utils');
const {workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
function testAWorkspace() {
export function testAWorkspace() {
setup(function() {
Blockly.defineBlocksWithJsonArray([{
"type": "get_var_block",
@@ -1526,4 +1528,3 @@ function testAWorkspace() {
});
});
}
exports.testAWorkspace = testAWorkspace;
+2 -1
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.theme');
const {assertEventFired} = goog.require('Blockly.test.helpers.events');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Theme', function() {
+3 -2
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.toolbox');
const {defineStackBlock, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {getBasicToolbox, getCategoryJSON, getChildItem, getCollapsibleItem, getDeeplyNestedJSON, getInjectedToolbox, getNonCollapsibleItem, getSeparator, getSimpleJson, getXmlArray} = goog.require('Blockly.test.toolboxHelpers');
const {defineStackBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {getBasicToolbox, getCategoryJSON, getChildItem, getCollapsibleItem, getDeeplyNestedJSON, getInjectedToolbox, getNonCollapsibleItem, getSeparator, getSimpleJson, getXmlArray} = goog.require('Blockly.test.helpers.toolboxDefinitions');
suite('Toolbox', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.tooltip');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Tooltip', function() {
+4 -1
View File
@@ -6,8 +6,11 @@
goog.module('Blockly.test.trashcan');
const {assertEventFired, assertEventNotFired} = goog.require('Blockly.test.helpers.events');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {defineBasicBlockWithField, defineMutatorBlocks, defineRowBlock, defineStackBlock, defineStatementBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, assertEventNotFired, defineBasicBlockWithField, defineRowBlock, defineStatementBlock, defineStackBlock, defineMutatorBlocks, sharedTestSetup, sharedTestTeardown, simulateClick} = goog.require('Blockly.test.helpers');
const {simulateClick} = goog.require('Blockly.test.helpers.userInput');
suite("Trashcan", function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.utils');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Utils', function() {
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.variableMap');
const {assertVariableValues, createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {assertVariableValues} = goog.require('Blockly.test.helpers.variables');
const {createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Variable Map', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.variableModel');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Variable Model', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.variables');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Variables', function() {
+1 -1
View File
@@ -6,7 +6,7 @@
goog.module('Blockly.test.widgetDiv');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('WidgetDiv', function() {
+1 -1
View File
@@ -7,7 +7,7 @@
goog.module('Blockly.test.workspaceComment');
goog.require('Blockly.WorkspaceComment');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
suite('Workspace comment', function() {
+5 -2
View File
@@ -6,9 +6,12 @@
goog.module('Blockly.test.workspaceSvg');
const {assertEventFired, assertEventNotFired, createFireChangeListenerSpy} = goog.require('Blockly.test.helpers.events');
const {assertVariableValues} = goog.require('Blockly.test.helpers.variables');
const {defineStackBlock} = goog.require('Blockly.test.helpers.blockDefinitions');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, assertEventNotFired, assertVariableValues, createFireChangeListenerSpy, defineStackBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {testAWorkspace} = goog.require('Blockly.test.workspaceHelpers');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {testAWorkspace} = goog.require('Blockly.test.helpers.workspace');
suite('WorkspaceSvg', function() {
+3 -2
View File
@@ -6,8 +6,9 @@
goog.module('Blockly.test.workspace');
const {assertVariableValues, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {testAWorkspace} = goog.require('Blockly.test.workspaceHelpers');
const {assertVariableValues} = goog.require('Blockly.test.helpers.variables');
const {sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {testAWorkspace} = goog.require('Blockly.test.helpers.workspace');
suite('Workspace', function() {
+2 -1
View File
@@ -6,7 +6,8 @@
goog.module('Blockly.test.xml');
const {addBlockTypeToCleanup, assertVariableValues, createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {addBlockTypeToCleanup, createGenUidStubWithReturns, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {assertVariableValues} = goog.require('Blockly.test.helpers.variables');
suite('XML', function() {
+3 -1
View File
@@ -6,8 +6,10 @@
goog.module('Blockly.test.zoomControls');
const {assertEventFired, assertEventNotFired} = goog.require('Blockly.test.helpers.events');
const eventUtils = goog.require('Blockly.Events.utils');
const {assertEventFired, assertEventNotFired, sharedTestSetup, sharedTestTeardown, simulateClick} = goog.require('Blockly.test.helpers');
const {sharedTestSetup, sharedTestTeardown} = goog.require('Blockly.test.helpers.setupTeardown');
const {simulateClick} = goog.require('Blockly.test.helpers.userInput');
suite("Zoom Controls", function() {