From 5ce8c68833d0e5946372f3333f7a165478431402 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini <16690124+samelhusseini@users.noreply.github.com> Date: Tue, 30 Jul 2019 11:13:52 -0700 Subject: [PATCH] Fix node build and add node tests (#2736) * Fix node build and add node tests --- blockly_compressed.js | 75 +++++++++++++++++++------------------ blockly_uncompressed.js | 20 +++------- core/utils.js | 6 +-- core/utils/base.js | 38 +++++++++++++++++++ core/utils/dom.js | 14 ++++++- core/utils/useragent.js | 3 +- core/xml.js | 10 ++--- gulpfile.js | 10 ++--- tests/node/.eslintrc.json | 14 +++++++ tests/node/mocha.opts | 3 ++ tests/node/run_node_test.js | 63 +++++++++++++++++++++++++++++++ tests/run_all_tests.sh | 3 ++ 12 files changed, 188 insertions(+), 71 deletions(-) create mode 100644 core/utils/base.js create mode 100644 tests/node/.eslintrc.json create mode 100644 tests/node/mocha.opts create mode 100644 tests/node/run_node_test.js diff --git a/blockly_compressed.js b/blockly_compressed.js index b7721c6f6..8d800bc26 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -879,7 +879,7 @@ goog.ui.tree.TreeControl.prototype.handleMouseEvent_=function(a){goog.log.fine(t goog.ui.tree.TreeControl.prototype.handleKeyEvent=function(a){var b;(b=this.typeAhead_.handleNavigation(a)||this.selectedItem_&&this.selectedItem_.onKeyDown(a)||this.typeAhead_.handleTypeAheadChar(a))&&a.preventDefault();return b};goog.ui.tree.TreeControl.prototype.getNodeFromEvent_=function(a){for(var b=a.target;null!=b;){if(a=goog.ui.tree.BaseNode.allNodes[b.id])return a;if(b==this.getElement())break;b=b.parentNode}return null}; goog.ui.tree.TreeControl.prototype.createNode=function(a){return new goog.ui.tree.TreeNode(a||goog.html.SafeHtml.EMPTY,this.getConfig(),this.getDomHelper())};goog.ui.tree.TreeControl.prototype.setNode=function(a){this.typeAhead_.setNodeInMap(a)};goog.ui.tree.TreeControl.prototype.removeNode=function(a){this.typeAhead_.removeNodeFromMap(a)};goog.ui.tree.TreeControl.prototype.clearTypeAhead=function(){this.typeAhead_.clear()};goog.ui.tree.TreeControl.defaultConfig=goog.ui.tree.BaseNode.defaultConfig; var Blockly={};Blockly.Blocks=Object.create(null);Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"}; -Blockly.utils={};Blockly.utils.Coordinate=function(a,b){this.x=a;this.y=b};Blockly.utils.Coordinate.equals=function(a,b){return a==b?!0:a&&b?a.x==b.x&&a.y==b.y:!1};Blockly.utils.Coordinate.distance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)};Blockly.utils.Coordinate.magnitude=function(a){return Math.sqrt(a.x*a.x+a.y*a.y)};Blockly.utils.Coordinate.difference=function(a,b){return new Blockly.utils.Coordinate(a.x-b.x,a.y-b.y)}; +Blockly.utils={};Blockly.utils.base={};Blockly.utils.global=this||self;Blockly.utils.Coordinate=function(a,b){this.x=a;this.y=b};Blockly.utils.Coordinate.equals=function(a,b){return a==b?!0:a&&b?a.x==b.x&&a.y==b.y:!1};Blockly.utils.Coordinate.distance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)};Blockly.utils.Coordinate.magnitude=function(a){return Math.sqrt(a.x*a.x+a.y*a.y)};Blockly.utils.Coordinate.difference=function(a,b){return new Blockly.utils.Coordinate(a.x-b.x,a.y-b.y)}; Blockly.utils.Coordinate.sum=function(a,b){return new Blockly.utils.Coordinate(a.x+b.x,a.y+b.y)};Blockly.utils.Coordinate.prototype.scale=function(a){this.x*=a;this.y*=a;return this};Blockly.utils.Coordinate.prototype.translate=function(a,b){this.x+=a;this.y+=b;return this};Blockly.utils.string={};Blockly.utils.string.startsWith=function(a,b){return 0==a.lastIndexOf(b,0)};Blockly.utils.string.shortestStringLength=function(a){return a.length?a.reduce(function(a,c){return a.lengthd&&(d=h,e=g)}return e?Blockly.utils.string.wrapMutate_(a,e,c):b};Blockly.utils.string.wrapToText_=function(a,b){for(var c=[],d=0;d"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1");return a.replace(/^\n/,"")}; Blockly.Xml.textToDom=function(a){var b=Blockly.utils.xml.textToDomDocument(a);if(!b||!b.documentElement||b.getElementsByTagName("parsererror").length)throw Error("textToDom was unable to parse: "+a);return b.documentElement};Blockly.Xml.clearWorkspaceAndLoadFromXml=function(a,b){b.setResizesEnabled(!1);b.clear();var c=Blockly.Xml.domToWorkspace(a,b);b.setResizesEnabled(!0);return c}; Blockly.Xml.domToWorkspace=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());c=[];Blockly.Field.startCache();var e=a.childNodes.length,f=Blockly.Events.getGroup();f||Blockly.Events.setGroup(!0);b.setResizesEnabled&&b.setResizesEnabled(!1);var g=!0;try{for(var h=0;h=this.height_||0>=this.width_)throw Error("Height and width values of an image field must be greater than 0.");this.size_=new goog.math.Size(this.width_,this.height_+2*Blockly.BlockSvg.INLINE_PADDING_Y);this.flipRtl_=f;this.text_= d||"";this.setValue(a||"");"function"==typeof e&&(this.clickHandler_=e)};goog.inherits(Blockly.FieldImage,Blockly.Field);Blockly.FieldImage.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.src),c=Number(Blockly.utils.replaceMessageReferences(a.width)),d=Number(Blockly.utils.replaceMessageReferences(a.height)),e=Blockly.utils.replaceMessageReferences(a.alt);return new Blockly.FieldImage(b,c,d,e,null,!!a.flipRtl)};Blockly.FieldImage.prototype.EDITABLE=!1; Blockly.FieldImage.prototype.isDirty_=!1;Blockly.FieldImage.prototype.initView=function(){this.imageElement_=Blockly.utils.dom.createSvgElement("image",{height:this.height_+"px",width:this.width_+"px",alt:this.text_},this.fieldGroup_);this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.value_)};Blockly.FieldImage.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:a}; -Blockly.FieldImage.prototype.doValueUpdate_=function(a){this.value_=a;this.imageElement_&&this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.value_||"")};Blockly.FieldImage.prototype.getFlipRtl=function(){return this.flipRtl_};Blockly.FieldImage.prototype.setText=function(a){null!==a&&(this.text_=a,this.imageElement_&&this.imageElement_.setAttribute("alt",a||""))};Blockly.FieldImage.prototype.showEditor_=function(){this.clickHandler_&&this.clickHandler_(this)}; -Blockly.FieldImage.prototype.setOnClickHandler=function(a){this.clickHandler_=a};Blockly.FieldImage.prototype.getCorrectedSize=function(){this.getSize();return new goog.math.Size(this.size_.width,this.height_+1)};Blockly.Field.register("field_image",Blockly.FieldImage);Blockly.FieldNumber=function(a,b,c,d,e){this.setConstraints(b,c,d);a=this.doClassValidation_(a);null===a&&(a=0);Blockly.FieldNumber.superClass_.constructor.call(this,a,e)};goog.inherits(Blockly.FieldNumber,Blockly.FieldTextInput);Blockly.FieldNumber.fromJson=function(a){return new Blockly.FieldNumber(a.value,a.min,a.max,a.precision)};Blockly.FieldNumber.prototype.SERIALIZABLE=!0; +Blockly.FieldImage.prototype.doValueUpdate_=function(a){this.value_=a;this.imageElement_&&this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.value_||"")};Blockly.FieldImage.prototype.getFlipRtl=function(){return this.flipRtl_};Blockly.FieldImage.prototype.setText=function(a){this.setAlt(a)};Blockly.FieldImage.prototype.setAlt=function(a){null!==a&&(this.text_=a,this.imageElement_&&this.imageElement_.setAttribute("alt",a||""))}; +Blockly.FieldImage.prototype.showEditor_=function(){this.clickHandler_&&this.clickHandler_(this)};Blockly.FieldImage.prototype.setOnClickHandler=function(a){this.clickHandler_=a};Blockly.FieldImage.prototype.getCorrectedSize=function(){this.getSize();return new goog.math.Size(this.size_.width,this.height_+1)};Blockly.Field.register("field_image",Blockly.FieldImage);Blockly.FieldNumber=function(a,b,c,d,e){this.setConstraints(b,c,d);a=this.doClassValidation_(a);null===a&&(a=0);Blockly.FieldNumber.superClass_.constructor.call(this,a,e)};goog.inherits(Blockly.FieldNumber,Blockly.FieldTextInput);Blockly.FieldNumber.fromJson=function(a){return new Blockly.FieldNumber(a.value,a.min,a.max,a.precision)};Blockly.FieldNumber.prototype.SERIALIZABLE=!0; Blockly.FieldNumber.prototype.setConstraints=function(a,b,c){c=parseFloat(c);this.precision_=isNaN(c)?0:c;c=this.precision_.toString();var d=c.indexOf(".");this.fractionalDigits_=-1==d?-1:c.length-(d+1);a=parseFloat(a);this.min_=isNaN(a)?-Infinity:a;b=parseFloat(b);this.max_=isNaN(b)?Infinity:b;this.setValue(this.getValue())}; Blockly.FieldNumber.prototype.doClassValidation_=function(a){if(null===a||void 0===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=parseFloat(a||0);if(isNaN(a))return null;a=Math.min(Math.max(a,this.min_),this.max_);this.precision_&&isFinite(a)&&(a=Math.round(a/this.precision_)*this.precision_);return a=-1==this.fractionalDigits_?a:Number(a.toFixed(this.fractionalDigits_))};Blockly.Field.register("field_number",Blockly.FieldNumber);Blockly.FieldVariable=function(a,b,c,d){this.menuGenerator_=Blockly.FieldVariable.dropdownCreate;this.size_=new goog.math.Size(0,Blockly.BlockSvg.MIN_BLOCK_Y);this.setValidator(b);this.defaultVariableName=a||"";this.setTypes_(c,d);this.value_=null};goog.inherits(Blockly.FieldVariable,Blockly.FieldDropdown);Blockly.FieldVariable.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.variable);return new Blockly.FieldVariable(b,null,a.variableTypes,a.defaultType)}; Blockly.FieldVariable.prototype.workspace_=null;Blockly.FieldVariable.prototype.SERIALIZABLE=!0;Blockly.FieldVariable.prototype.initModel=function(){if(!this.variable_){var a=Blockly.Variables.getOrCreateVariablePackage(this.workspace_,null,this.defaultVariableName,this.defaultType_);Blockly.Events.disable();this.setValue(a.getId());Blockly.Events.enable()}}; @@ -1781,7 +1782,7 @@ Blockly.FieldVariable.prototype.getValue=function(){return this.variable_?this.v Blockly.FieldVariable.prototype.doClassValidation_=function(a){var b=Blockly.Variables.getVariable(this.workspace_,a);if(!b)return console.warn("Variable id doesn't point to a real variable! ID was "+a),null;b=b.type;return this.typeIsAllowed_(b)?a:(console.warn("Variable type doesn't match this field! Type was "+b),null)}; Blockly.FieldVariable.prototype.doValueUpdate_=function(a){this.variable_=Blockly.Variables.getVariable(this.workspace_,a);this.value_=a;this.text_=this.variable_.name;this.isDirty_=!0};Blockly.FieldVariable.prototype.typeIsAllowed_=function(a){var b=this.getVariableTypes_();if(!b)return!0;for(var c=0;c level. It's all whitespace anyway. continue; } @@ -615,7 +615,7 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) { var childBlockElement = null; var childShadowElement = null; for (var j = 0, grandchild; grandchild = xmlChild.childNodes[j]; j++) { - if (grandchild.nodeType == Node.ELEMENT_NODE) { + if (grandchild.nodeType == Blockly.utils.dom.Node.ELEMENT_NODE) { if (grandchild.nodeName.toLowerCase() == 'block') { childBlockElement = /** @type {!Element} */ (grandchild); } else if (grandchild.nodeName.toLowerCase() == 'shadow') { diff --git a/gulpfile.js b/gulpfile.js index c870e1b77..7f9eab613 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -62,18 +62,14 @@ gulp.task('blockly_javascript_en', function() { .pipe(insert.append(` if (typeof DOMParser !== 'function') { var JSDOM = require('jsdom').JSDOM; + var window = (new JSDOM()).window; + var document = window.document; + var Element = window.Element; Blockly.utils.xml.textToDomDocument = function(text) { var jsdom = new JSDOM(text, { contentType: 'text/xml' }); return jsdom.window.document; }; } -if (typeof Node !== 'function') { - var Node = { - ELEMENT_NODE: 1, - TEXT_NODE: 3, - DOCUMENT_POSITION_CONTAINED_BY: 16 - }; -} if (typeof module === 'object') { module.exports = Blockly; } if (typeof window === 'object') { window.Blockly = Blockly; }\n`)) .pipe(gulp.dest('.')); diff --git a/tests/node/.eslintrc.json b/tests/node/.eslintrc.json new file mode 100644 index 000000000..50215619b --- /dev/null +++ b/tests/node/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "parserOptions": { + "ecmaVersion": 6 + }, + "env": { + "browser": false, + "mocha": true + }, + "globals": { + "console": true, + "require": true + }, + "extends": "../../.eslintrc.json" +} diff --git a/tests/node/mocha.opts b/tests/node/mocha.opts new file mode 100644 index 000000000..240bd1610 --- /dev/null +++ b/tests/node/mocha.opts @@ -0,0 +1,3 @@ +# mocha.opts +--ui tdd +--reporter landing diff --git a/tests/node/run_node_test.js b/tests/node/run_node_test.js new file mode 100644 index 000000000..d934f8355 --- /dev/null +++ b/tests/node/run_node_test.js @@ -0,0 +1,63 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2019 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Mocha tests that test Blockly in Node. + */ + +var assert = require('chai').assert; +var Blockly = require('../../blockly_node_javascript_en.js'); + +var xmlText = ` + + + + Hello from Blockly! + + + +`; + +suite('Test Node.js', function() { + test('Import XML', function() { + assert.doesNotThrow(function() { + const xml = Blockly.Xml.textToDom(xmlText); + + // Create workspace and import the XML + const workspace = new Blockly.Workspace(); + Blockly.Xml.domToWorkspace(xml, workspace); + + }, "Failed to import XML"); + }); + test('Generate Code', function() { + const xml = Blockly.Xml.textToDom(xmlText); + + // Create workspace and import the XML + const workspace = new Blockly.Workspace(); + Blockly.Xml.domToWorkspace(xml, workspace); + + // Convert code + const code = Blockly.JavaScript.workspaceToCode(workspace); + + // Check output + assert.equal(`window.alert('Hello from Blockly!');`, code.trim(), 'equal'); + }); +}); + diff --git a/tests/run_all_tests.sh b/tests/run_all_tests.sh index f0d4695d7..c73a4cfd1 100755 --- a/tests/run_all_tests.sh +++ b/tests/run_all_tests.sh @@ -61,6 +61,9 @@ run_test_command "jsunit" "node tests/jsunit/run_jsunit_tests_in_browser.js" # Run Mocha tests inside a browser. run_test_command "mocha" "node tests/mocha/run_mocha_tests_in_browser.js" +# Run Node tests. +run_test_command "node" "./node_modules/.bin/mocha tests/node --opts tests/node/mocha.opts" + # Run generator tests inside a browser and check the results. run_test_command "generators" "tests/scripts/run_generators.sh"