checking the Blocks with the solution using the XML strings
This commit is contained in:
		
							parent
							
								
									f14508a5ca
								
							
						
					
					
						commit
						ab016610bd
					
				| @ -38,7 +38,6 @@ class BlocklyWindow extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     console.log(this.props.initialXml); |  | ||||||
|     return ( |     return ( | ||||||
|       <BlocklyComponent ref={this.simpleWorkspace} |       <BlocklyComponent ref={this.simpleWorkspace} | ||||||
|         style={this.props.blocklyCSS} |         style={this.props.blocklyCSS} | ||||||
|  | |||||||
| @ -2,8 +2,6 @@ import React, { Component } from 'react'; | |||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
| 
 | 
 | ||||||
| import * as Blockly from 'blockly/core'; |  | ||||||
| 
 |  | ||||||
| import BlocklyWindow from '../Blockly/BlocklyWindow'; | import BlocklyWindow from '../Blockly/BlocklyWindow'; | ||||||
| 
 | 
 | ||||||
| import { tutorials } from './tutorials'; | import { tutorials } from './tutorials'; | ||||||
| @ -15,7 +13,6 @@ class Instruction extends Component { | |||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var currentTutorialId = this.props.currentTutorialId; |     var currentTutorialId = this.props.currentTutorialId; | ||||||
|     console.log(currentTutorialId); |  | ||||||
|     return ( |     return ( | ||||||
|       tutorials[currentTutorialId].instruction ? |       tutorials[currentTutorialId].instruction ? | ||||||
|         <div> |         <div> | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import * as Blockly from 'blockly/core'; | |||||||
| import Compile from '../Compile'; | import Compile from '../Compile'; | ||||||
| 
 | 
 | ||||||
| import { tutorials } from './tutorials'; | import { tutorials } from './tutorials'; | ||||||
|  | import { checkXml } from './compareXml'; | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from '@material-ui/core/IconButton'; | ||||||
| @ -49,7 +50,7 @@ class SolutionCheck extends Component { | |||||||
| 
 | 
 | ||||||
|   check = () => { |   check = () => { | ||||||
|     const workspace = Blockly.getMainWorkspace(); |     const workspace = Blockly.getMainWorkspace(); | ||||||
|     var msg = tutorials[this.props.currentTutorialId].test(workspace); |     var msg = checkXml(tutorials[this.props.currentTutorialId].solution, this.props.xml); | ||||||
|     this.props.tutorialCheck(msg.type); |     this.props.tutorialCheck(msg.type); | ||||||
|     this.setState({ msg, open: true }); |     this.setState({ msg, open: true }); | ||||||
|   } |   } | ||||||
| @ -97,13 +98,16 @@ class SolutionCheck extends Component { | |||||||
|   }; |   }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| SolutionCheck.propTypes = { | SolutionCheck.propTypes = { | ||||||
|   tutorialCheck: PropTypes.func.isRequired, |   tutorialCheck: PropTypes.func.isRequired, | ||||||
|   currentTutorialId: PropTypes.number |   currentTutorialId: PropTypes.number, | ||||||
|  |   xml: PropTypes.string.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   currentTutorialId: state.tutorial.currentId |   currentTutorialId: state.tutorial.currentId, | ||||||
|  |   xml: state.workspace.code.xml | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { tutorialCheck })(withStyles(styles, {withTheme: true})(SolutionCheck)); | export default connect(mapStateToProps, { tutorialCheck })(withStyles(styles, {withTheme: true})(SolutionCheck)); | ||||||
|  | |||||||
| @ -43,7 +43,6 @@ class Tutorial extends Component { | |||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var currentTutorialId = this.props.currentTutorialId; |     var currentTutorialId = this.props.currentTutorialId; | ||||||
|     console.log(this.props); |  | ||||||
|     return ( |     return ( | ||||||
|       !Number.isInteger(currentTutorialId) || currentTutorialId+1 < 1 || currentTutorialId+1 > tutorials.length ? |       !Number.isInteger(currentTutorialId) || currentTutorialId+1 < 1 || currentTutorialId+1 > tutorials.length ? | ||||||
|         <NotFound button={{title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial'}}/> |         <NotFound button={{title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial'}}/> | ||||||
|  | |||||||
							
								
								
									
										78
									
								
								src/components/Tutorial/compareXml.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/components/Tutorial/compareXml.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | |||||||
|  | export const checkXml = (originalXmlString, userXmlString) => { | ||||||
|  |   var originalXml = parseXml(originalXmlString); | ||||||
|  |   var userXml = parseXml(userXmlString); | ||||||
|  |   return compareXml(originalXml, userXml); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const parseXml = (xmlString) => { | ||||||
|  |   var parser = new DOMParser(); | ||||||
|  |   var xmlDoc = parser.parseFromString(xmlString, "text/xml"); | ||||||
|  |   return xmlDoc; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const compareNumberOfBlocks = (originalBlocks, userBlocks) => { | ||||||
|  |   if(originalBlocks.length !== userBlocks.length){ | ||||||
|  |     if(originalBlocks.length > userBlocks.length){ | ||||||
|  |       return {text: 'Es wurden zu wenig Blöcke verwendet.', type: 'error'}; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       return {text: 'Es wurden zu viele Blöcke verwendet.', type: 'error'}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const compareBlockType = (originalBlock, userBlock, index) => { | ||||||
|  |   if(originalBlock.attributes['type'].value !== userBlock.attributes['type'].value){ | ||||||
|  |     return {text: `Es wurde ein falscher Blocktyp an Position ${index+1} verwendet`, type: 'error'}; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const compareParentBlock = (originalBlock, userBlock, index) => { | ||||||
|  |   // using parentNode instead of parenElement
 | ||||||
|  |   // see https://stackoverflow.com/questions/8685739/difference-between-dom-parentnode-and-parentelement
 | ||||||
|  |   if(originalBlock.parentNode.attributes['name']){ | ||||||
|  |     if(userBlock.parentNode.attributes['name']){ | ||||||
|  |       // do the blocks have the same name-properties?
 | ||||||
|  |       if(originalBlock.parentNode.attributes['name'].value !== userBlock.parentNode.attributes['name'].value){ | ||||||
|  |         if(userBlock.parentNode.attributes['name'].value === 'LOOP_FUNC' || userBlock.parentNode.attributes['name'].value === 'SETUP_FUNC'){ | ||||||
|  |           return {text: `Der Block mit dem Typen '${userBlock.attributes['type'].value}' wurde irrtümlicherweise in die ${userBlock.parentNode.attributes['name'].value === 'SETUP_FUNC' ? 'Setup' : 'Endlosschleifen'}-Funktion geschrieben.
 | ||||||
|  |                         Verschiebe den gesamten Block (und alle dazugehörigen Blöcke) in die ${userBlock.parentNode.attributes['name'].value !== 'SETUP_FUNC' ? 'Setup' : 'Endlosschleifen'}-Funktion.`, type: 'error'};
 | ||||||
|  |         } | ||||||
|  |         // TODO: has a block two name-properties?
 | ||||||
|  |         return {text: `Der Block mit dem Typen '${userBlock.attributes['type'].value}' hat ein falsches 'name'-Attribut`, type: 'error'}; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     // user-block has not a name-attribute
 | ||||||
|  |     else { | ||||||
|  |       // do the user-block has a xmlns-attribute -> user-block is not connected
 | ||||||
|  |       if(userBlock.parentNode.attributes['xmlns']){ | ||||||
|  |         return {text: `Der Block mit dem Typen '${userBlock.attributes['type'].value}' hat keine Verbindung zu einem anderen Block.`, type: 'error'}; | ||||||
|  |       } | ||||||
|  |       // user-block has not a xmlns- AND name-attribute
 | ||||||
|  |       else { | ||||||
|  |           return {text: `Der Block an Position ${index+1} ist falsch eingeordnet. Tipp: Block an Position ${index+1} einem vorherigen Block unterordnen.`, type: 'error'}; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const compareXml = (originalXml, userXml) => { | ||||||
|  |   var originalItemList = originalXml.getElementsByTagName("block"); | ||||||
|  |   var userItemList = userXml.getElementsByTagName("block"); | ||||||
|  | 
 | ||||||
|  |   // compare number of blocks
 | ||||||
|  |   var number = compareNumberOfBlocks(originalItemList, userItemList); | ||||||
|  |   if(number){return number;} | ||||||
|  | 
 | ||||||
|  |   for(var i=0; i < originalItemList.length; i++){ | ||||||
|  |     // compare type
 | ||||||
|  |     var type = compareBlockType(originalItemList[i], userItemList[i], i); | ||||||
|  |     if(type){return type;} | ||||||
|  | 
 | ||||||
|  |     // compare name
 | ||||||
|  |     var parent = compareParentBlock(originalItemList[i], userItemList[i], i); | ||||||
|  |     if(parent){return parent;} | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return {text: 'Super. Alles richtig!', type: 'success'}; | ||||||
|  | }; | ||||||
| @ -18,6 +18,23 @@ export const tutorials = [ | |||||||
|                   </block> |                   </block> | ||||||
|                 </xml>` |                 </xml>` | ||||||
|       }, |       }, | ||||||
|  |     "solution": `<xml xmlns="https://developers.google.com/blockly/xml">
 | ||||||
|  |                   <block type="arduino_functions" id="QWW|$jB8+*EL;}|#uA" deletable="false" x="37" y="20"> | ||||||
|  |                     <statement name="LOOP_FUNC"> | ||||||
|  |                       <block type="sensebox_telegram_do" id="K%yUabqRVQ{]9eX-8jZD"> | ||||||
|  |                         <statement name="telegram_do"> | ||||||
|  |                           <block type="controls_if" id="rA6:!p7,{y2MOuVpv[Pm"> | ||||||
|  |                             <value name="IF0"> | ||||||
|  |                               <block type="logic_boolean" id="=[Zh}O6_)fl?JD#2)2bL"> | ||||||
|  |                                 <field name="BOOL">TRUE</field> | ||||||
|  |                               </block> | ||||||
|  |                             </value> | ||||||
|  |                           </block> | ||||||
|  |                         </statement> | ||||||
|  |                       </block> | ||||||
|  |                     </statement> | ||||||
|  |                   </block> | ||||||
|  |                 </xml>`, | ||||||
|     "test": function(workspace){ |     "test": function(workspace){ | ||||||
|               var wifi = workspace.getBlocksByType('sensebox_wifi'); // result is an array with Blocks as objects
 |               var wifi = workspace.getBlocksByType('sensebox_wifi'); // result is an array with Blocks as objects
 | ||||||
|               if(wifi.length > 0){ |               if(wifi.length > 0){ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user