diff --git a/sanityCheck b/sanityCheck index 1db33d90dcf53ef83a2ccb6ac9f086afe8d56d3a..eaf44496fcfb1d1c5c32abcf01436e2ddd91969d 100755 --- a/sanityCheck +++ b/sanityCheck @@ -79,7 +79,7 @@ $GREP -e "<<[a-zA-Z]* = *" -- src/*.tw | myprint "BadCommand" # Check for duplicate words, e.g. with with $GREP -e " \(\b[a-zA-Z][a-zA-Z]\+\) \1\b " --and --not -e " her her " --and --not -e " you you " --and --not -e " New New " --and --not -e " that that " --and --not -e " in in " --and --not -e " is is " -- 'src/*' | myprint "Duplicate words" # Check for obsolete SugarCube macros -$GREP -E "<<display|<<click|<<.*\.contains" -- src/*.tw | myprint "ObsoleteMacro" +$GREP -E "<<display |<<click|<<.*\.contains" -- src/*.tw | myprint "ObsoleteMacro" # Check for double articles $GREP -E "\Wa an\W" -- src/*.tw | myprint "DoubleArticle" # Check for incorrect articles diff --git a/src/debugging/debugJS.tw b/src/debugging/debugJS.tw new file mode 100644 index 0000000000000000000000000000000000000000..80d70b39e0f778ec1025fddef7174c4a1cdb87ea --- /dev/null +++ b/src/debugging/debugJS.tw @@ -0,0 +1,70 @@ +:: DebugJS [script] + +/* +Given an object, this will return an array where for each property of the original object, we include the object +{variable: property, oldVal: _oldDiff.property, newVal: _newDiff.property} +*/ +window.generateDiffArray = function generateDiffArray(obj) { + var diffArray = Object.keys(obj).map(function(key) { + return {variable: key, oldVal: State.temporary.oldDiff[key], newVal: State.temporary.newDiff[key]}; + }); + return diffArray; +}; + +/* +Shamelessly copied from https://codereview.stackexchange.com/a/11580 +Finds and returns the difference between two objects. Potentially will have arbitrary nestings of objects. +*/ +window.difference = function difference(o1, o2) { + var k, kDiff, diff = {}; + for (k in o1) { + if (!o1.hasOwnProperty(k)) { + } else if (typeof o1[k] != 'object' || typeof o2[k] != 'object') { + if (!(k in o2) || o1[k] !== o2[k]) { + diff[k] = o2[k]; + } + } else if (kDiff = difference(o1[k], o2[k])) { + diff[k] = kDiff; + } + } + for (k in o2) { + if (o2.hasOwnProperty(k) && !(k in o1)) { + diff[k] = o2[k]; + } + } + for (k in diff) { + if (diff.hasOwnProperty(k)) { + return diff; + } + } + return false; +}; + +/* +Shamelessly copied from https://stackoverflow.com/a/19101235 +Flattens an object while concatenating property names. +For example {id: {number: 4, name: "A"}} --> {id.number: 4, id.name: "A"} +*/ +window.diffFlatten = function diffFlatten(data) { + var result = {}; + function recurse (cur, prop) { + if (Object(cur) !== cur) { + result[prop] = cur; + } else if (Array.isArray(cur)) { + for(var i=0, l=cur.length; i<l; i++) + recurse(cur[i], prop + "[" + i + "]"); + if (l == 0) + result[prop] = []; + } else { + var isEmpty = true; + for (var p in cur) { + isEmpty = false; + recurse(cur[p], prop ? prop+"."+p : p); + } + if (isEmpty && prop) + result[prop] = {}; + } + } + recurse(data, ""); + return result; +}; diff --git a/src/debugging/debugWidgets.tw b/src/debugging/debugWidgets.tw new file mode 100644 index 0000000000000000000000000000000000000000..3926d9a2d03ac4fc7d0ca8ac0af07c154a95f555 --- /dev/null +++ b/src/debugging/debugWidgets.tw @@ -0,0 +1,33 @@ +:: Debug Widgets [widget nobr] + +/* +$args[0] and $args[1] should both be objects. $args[0] is the old object, $args[1] is the new object. Will also work with arrays. +This widget will find which properties were changed, and display their original values and current values. +It's somewhat awkward if a stored variable changes types to/from an object or array. +Usage example: + <<set $slaves[0].hColor = "red">> + <<set _oldVariables = clone(State.variables)>> + <<set $slaves[0].hColor = "black">> + <<set _newVariables = clone(State.variables)>> + <<displayDifferences _oldVariables _newVariables>> +This will display "Variable: slaves.0.hColor, Original Value: red, New Value: black" with an option to show more (in this case the show more option gives the same display). +*/ +<<widget "displayDifferences">> +Differences:<br> +<<set _newDiff = diffFlatten(difference($args[0],$args[1]))>> /* returns a flattened object containing the names of the changed variables, and the new values of those variables */ +<<set _oldDiff = diffFlatten(difference($args[1],$args[0]))>> /* returns a flattened object containing the names of the changed variables, and the old values of those variables */ +<<set _diffArrayFromNew = generateDiffArray(_newDiff)>> /* this function requires the existence of the specific variables _newDiff AND _oldDiff to work */ +<<for _i = 0; _i < _diffArrayFromNew.length; _i++>> /* print variable names, and changed values. Will output the new values correctly, may not output old values correctly */ + Variable: <<print _diffArrayFromNew[_i].variable>>, Original Value: <<print _diffArrayFromNew[_i].oldVal>>, New Value: <<print _diffArrayFromNew[_i].newVal>><br> +<</for>> +<span id="extraInfo"> +<<link "Show more">> + <<replace "#extraInfo">> + <<set _diffArrayFromOld = generateDiffArray(_oldDiff)>> + <<for _i = 0; _i < _diffArrayFromOld.length; _i++>> /* print variable names, and changed values. Will output the old values correctly, may not output new values correctly */ + Variable: <<print _diffArrayFromOld[_i].variable>>, Original Value: <<print _diffArrayFromOld[_i].oldVal>>, New Value: <<print _diffArrayFromOld[_i].newVal>><br> + <</for>> + <</replace>> +<</link>>// This should only be necessary if a variable changes type to/from an object or array. In that case this will display the correct original value, but incorrect current value.// +</span> +<</widget>>