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() { | ||||
|     console.log(this.props.initialXml); | ||||
|     return ( | ||||
|       <BlocklyComponent ref={this.simpleWorkspace} | ||||
|         style={this.props.blocklyCSS} | ||||
|  | ||||
| @ -2,8 +2,6 @@ import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| import BlocklyWindow from '../Blockly/BlocklyWindow'; | ||||
| 
 | ||||
| import { tutorials } from './tutorials'; | ||||
| @ -15,7 +13,6 @@ class Instruction extends Component { | ||||
| 
 | ||||
|   render() { | ||||
|     var currentTutorialId = this.props.currentTutorialId; | ||||
|     console.log(currentTutorialId); | ||||
|     return ( | ||||
|       tutorials[currentTutorialId].instruction ? | ||||
|         <div> | ||||
|  | ||||
| @ -8,6 +8,7 @@ import * as Blockly from 'blockly/core'; | ||||
| import Compile from '../Compile'; | ||||
| 
 | ||||
| import { tutorials } from './tutorials'; | ||||
| import { checkXml } from './compareXml'; | ||||
| 
 | ||||
| import { withStyles } from '@material-ui/core/styles'; | ||||
| import IconButton from '@material-ui/core/IconButton'; | ||||
| @ -49,7 +50,7 @@ class SolutionCheck extends Component { | ||||
| 
 | ||||
|   check = () => { | ||||
|     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.setState({ msg, open: true }); | ||||
|   } | ||||
| @ -97,13 +98,16 @@ class SolutionCheck extends Component { | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| SolutionCheck.propTypes = { | ||||
|   tutorialCheck: PropTypes.func.isRequired, | ||||
|   currentTutorialId: PropTypes.number | ||||
|   currentTutorialId: PropTypes.number, | ||||
|   xml: PropTypes.string.isRequired | ||||
| }; | ||||
| 
 | ||||
| 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)); | ||||
|  | ||||
| @ -43,7 +43,6 @@ class Tutorial extends Component { | ||||
| 
 | ||||
|   render() { | ||||
|     var currentTutorialId = this.props.currentTutorialId; | ||||
|     console.log(this.props); | ||||
|     return ( | ||||
|       !Number.isInteger(currentTutorialId) || currentTutorialId+1 < 1 || currentTutorialId+1 > tutorials.length ? | ||||
|         <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> | ||||
|                 </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){ | ||||
|               var wifi = workspace.getBlocksByType('sensebox_wifi'); // result is an array with Blocks as objects
 | ||||
|               if(wifi.length > 0){ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user