mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
Fixed Node.transform not recursing over replaced parts of the node tree (see #349).
This commit is contained in:
parent
84aaada3df
commit
f7c5381a13
@ -7,6 +7,8 @@
|
||||
the expressions result, string representation, or tex representation.
|
||||
Thanks @FSMaxB.
|
||||
- Fixed #309: Function median mutating the input matrix. Thanks @FSMaxB.
|
||||
- Fixed `Node.transform` not recursing over replaced parts of the
|
||||
node tree (see #349).
|
||||
|
||||
|
||||
## 2015-04-22, version 1.6.0
|
||||
|
||||
1853
dist/math.js
vendored
1853
dist/math.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/math.map
vendored
2
dist/math.map
vendored
File diff suppressed because one or more lines are too long
23
dist/math.min.js
vendored
23
dist/math.min.js
vendored
File diff suppressed because one or more lines are too long
@ -152,20 +152,16 @@ Node.prototype.traverse = function (callback) {
|
||||
* @return {Node} Returns the original node or its replacement
|
||||
*/
|
||||
Node.prototype.transform = function (callback) {
|
||||
// check itself
|
||||
var replacement = callback(this, null, null);
|
||||
if (replacement !== this) {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
// traverse over all childs
|
||||
function _transform (node, callback) {
|
||||
return node.map(function(child, path, parent) {
|
||||
var replacement = callback(child, path, parent);
|
||||
return (replacement !== child) ? replacement : _transform(child, callback);
|
||||
return _transform(replacement, callback);
|
||||
});
|
||||
}
|
||||
return _transform(this, callback);
|
||||
|
||||
var replacement = callback(this, null, null);
|
||||
return _transform(replacement, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -164,7 +164,9 @@ describe('ArrayNode', function() {
|
||||
var e = c.transform(function (node) {
|
||||
return (node instanceof ArrayNode) ? d : node;
|
||||
});
|
||||
assert.strictEqual(e, d);
|
||||
|
||||
assert.notStrictEqual(e, c);
|
||||
assert.deepEqual(e, d);
|
||||
});
|
||||
|
||||
it ('should traverse an ArrayNode', function () {
|
||||
|
||||
@ -149,7 +149,8 @@ describe('AssignmentNode', function() {
|
||||
return node instanceof AssignmentNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.notStrictEqual(f, d);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should traverse an AssignmentNode', function () {
|
||||
|
||||
@ -177,7 +177,9 @@ describe('BlockNode', function() {
|
||||
var e = a.transform(function (node) {
|
||||
return node instanceof BlockNode ? d : node;
|
||||
});
|
||||
assert.strictEqual(e, d);
|
||||
|
||||
assert.notStrictEqual(e, a);
|
||||
assert.deepEqual(e, d);
|
||||
});
|
||||
|
||||
it ('should traverse a BlockNode', function () {
|
||||
|
||||
@ -179,9 +179,9 @@ describe('ConditionalNode', function() {
|
||||
});
|
||||
|
||||
assert.notStrictEqual(f, n);
|
||||
assert.strictEqual(f.condition, e);
|
||||
assert.deepEqual(f.trueExpr, a);
|
||||
assert.deepEqual(f.falseExpr, b);
|
||||
assert.deepEqual(f.condition, e);
|
||||
assert.deepEqual(f.trueExpr, a);
|
||||
assert.deepEqual(f.falseExpr, b);
|
||||
});
|
||||
|
||||
it ('should transform a ConditionalNodes trueExpr', function () {
|
||||
@ -196,9 +196,9 @@ describe('ConditionalNode', function() {
|
||||
});
|
||||
|
||||
assert.notStrictEqual(f, n);
|
||||
assert.deepEqual(f.condition, condition);
|
||||
assert.strictEqual(f.trueExpr, e);
|
||||
assert.deepEqual(f.falseExpr, b);
|
||||
assert.deepEqual(f.condition, condition);
|
||||
assert.deepEqual(f.trueExpr, e);
|
||||
assert.deepEqual(f.falseExpr, b);
|
||||
});
|
||||
|
||||
it ('should transform a ConditionalNodes falseExpr', function () {
|
||||
@ -215,7 +215,7 @@ describe('ConditionalNode', function() {
|
||||
assert.notStrictEqual(f, n);
|
||||
assert.deepEqual(f.condition, condition);
|
||||
assert.deepEqual(f.trueExpr, a);
|
||||
assert.strictEqual(f.falseExpr, e);
|
||||
assert.deepEqual(f.falseExpr, e);
|
||||
});
|
||||
|
||||
it ('should transform a ConditionalNode itself', function () {
|
||||
@ -229,7 +229,8 @@ describe('ConditionalNode', function() {
|
||||
return node instanceof ConditionalNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.notStrictEqual(f, n);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should clone a ConditionalNode itself', function () {
|
||||
|
||||
@ -98,13 +98,13 @@ describe('ConstantNode', function() {
|
||||
var c = a.transform(function (node) {
|
||||
return node instanceof ConstantNode && node.value == '2' ? b : node;
|
||||
});
|
||||
assert.strictEqual(c, b);
|
||||
assert.deepEqual(c, b);
|
||||
|
||||
// no match should leave the node as is
|
||||
var d = a.transform(function (node) {
|
||||
return node instanceof ConstantNode && node.value == '99' ? b : node;
|
||||
});
|
||||
assert.notStrictEqual(d, a);
|
||||
assert.notStrictEqual(d, a);
|
||||
assert.deepEqual(d, a);
|
||||
});
|
||||
|
||||
|
||||
@ -223,7 +223,8 @@ describe('FunctionAssignmentNode', function() {
|
||||
return node instanceof FunctionAssignmentNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.notStrictEqual(f, n);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should clone a FunctionAssignmentNode', function () {
|
||||
|
||||
@ -205,7 +205,7 @@ describe('FunctionNode', function() {
|
||||
return node instanceof FunctionNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should traverse a FunctionNode', function () {
|
||||
|
||||
@ -238,7 +238,8 @@ describe('IndexNode', function() {
|
||||
return node instanceof IndexNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.notStrictEqual(f, n);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should clone an IndexNode', function () {
|
||||
|
||||
@ -5,11 +5,13 @@ var math = require('../../../index');
|
||||
var Node = require('../../../lib/expression/node/Node');
|
||||
|
||||
describe('Node', function() {
|
||||
function MyNode () {}
|
||||
function MyNode (value) {
|
||||
this.value = value;
|
||||
}
|
||||
MyNode.prototype = new Node();
|
||||
MyNode.prototype.forEach = function () {};
|
||||
MyNode.prototype.map = function () {
|
||||
return new MyNode();
|
||||
return new MyNode(this.value);
|
||||
};
|
||||
|
||||
it ('should create a Node', function () {
|
||||
@ -22,7 +24,7 @@ describe('Node', function() {
|
||||
});
|
||||
|
||||
it ('should filter a Node', function () {
|
||||
var n = new MyNode();
|
||||
var n = new MyNode(2);
|
||||
|
||||
assert.deepEqual(n.filter(function () {return true}), [n]);
|
||||
assert.deepEqual(n.filter(function (node) {return node instanceof Node}), [n]);
|
||||
@ -30,30 +32,30 @@ describe('Node', function() {
|
||||
});
|
||||
|
||||
it ('should transform a Node', function () {
|
||||
var a = new MyNode();
|
||||
var b = new MyNode();
|
||||
var a = new MyNode(2);
|
||||
var b = new MyNode(3);
|
||||
var c = a.transform(function (node) {
|
||||
return b;
|
||||
});
|
||||
assert.strictEqual(c, b);
|
||||
assert.deepEqual(c, b);
|
||||
|
||||
// no match
|
||||
a = new MyNode();
|
||||
b = new MyNode();
|
||||
a = new MyNode(2);
|
||||
b = new MyNode(3);
|
||||
c = a.transform(function (node) {
|
||||
return node;
|
||||
});
|
||||
assert.notStrictEqual(c, a);
|
||||
assert.deepEqual(c, a);
|
||||
});
|
||||
|
||||
it ('should transform a Node using a replacement function', function () {
|
||||
var a = new MyNode();
|
||||
var b = new MyNode();
|
||||
var a = new MyNode(2);
|
||||
var b = new MyNode(3);
|
||||
var c = a.transform(function (node) {
|
||||
assert.deepEqual(node, a);
|
||||
return b;
|
||||
});
|
||||
assert.strictEqual(c, b);
|
||||
assert.deepEqual(c, b);
|
||||
});
|
||||
|
||||
it ('should throw an error when cloning a Node interface', function () {
|
||||
|
||||
@ -140,10 +140,6 @@ describe('OperatorNode', function() {
|
||||
return node instanceof SymbolNode && node.name == 'x' ? f : node;
|
||||
});
|
||||
|
||||
assert.notStrictEqual(g, e);
|
||||
assert.notStrictEqual(g.args[0], e.args[0]);
|
||||
assert.strictEqual(g.args[0].args[0], f);
|
||||
assert.deepEqual(g.args[0].args[1], b);
|
||||
assert.deepEqual(g.args[1], f);
|
||||
});
|
||||
|
||||
|
||||
@ -197,7 +197,7 @@ describe('RangeNode', function() {
|
||||
return node instanceof RangeNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should clone a RangeNode', function () {
|
||||
|
||||
@ -277,7 +277,7 @@ describe('UpdateNode', function() {
|
||||
return node instanceof UpdateNode ? e : node;
|
||||
});
|
||||
|
||||
assert.strictEqual(f, e);
|
||||
assert.deepEqual(f, e);
|
||||
});
|
||||
|
||||
it ('should clone an UpdateNode', function () {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user