你如何检查一个函数 returns 是否是 Jasmine 中的一个对象?
How do you check if a function returns an object in Jasmine?
示例:
expect(bst.find(5)).toBe(<an object>);
我如何确定它是具有以下三个属性的对象:val
、left
和 right
?
编辑:
这有效 - http://jsfiddle.net/1d9h2L2z/1/
但这不是:
describe('A Binary Search Tree', function() {
var bst;
beforeEach(function() {
this.addMatchers({
toBeANode: function () {
return this.actual.val !== undefined && this.actual.left !== undefined && this.actual.right !== undefined;
}
});
bst = new BST();
bst.insert(4);
bst.insert(2);
bst.insert(1);
bst.insert(3);
bst.insert(6);
bst.insert(5);
bst.insert(7);
// 4
// 2 6
// 1 3 5 7
});
it('can do preorder traversal', function() {
expect(bst.preorder()).toBe('4213657');
});
it('can do inorder traversal', function() {
expect(bst.inorder()).toBe('1234567');
});
it('can do postorder traversal', function() {
expect(bst.postorder()).toBe('1325764');
});
it('can do levelorder traversal', function() {
expect(bst.levelorder()).toBe('4261357');
});
it('can get the minimum', function() {
expect(bst.min()).toBeANode();
expect(bst.min().val).toBe(1);
});
it('can get the maximum', function() {
expect(bst.max()).toBeANode();
expect(bst.max().val).toBe(7);
});
it('can find', function() {
expect(bst.find(5)).toBeANode();
expect(bst.find(5).val).toBe(5);
expect(bst.find(10)).toBe(-1);
});
it('can findParent', function() {
expect(bst.findParent(5)).toBeANode();
expect(bst.findParent(5).val).toBe(6);
expect(bst.findParent(8)).toBe(-1); // nonexistant node
expect(bst.findParent(4)).toBe(-1); // root
});
it('can remove a leaf node', function() {
bst.remove(7);
expect(bst.inorder()).toBe('123456');
});
it('can remove a node with one child', function() {
bst.insert(8);
bst.remove(7);
expect(bst.inorder()).toBe('1234568');
});
it('can remove a node with two children', function() {
bst.insert(2.1);
bst.remove(2);
expect(bst.inorder()).toBe('12.134567'); // right subtree has a left subtree
bst.insert(8);
bst.remove(6);
expect(bst.inorder()).toBe('12.134578'); // right subtree doesn't have a left subtree
});
// add AVL stuff
});
英国夏令时:
function BSTNode(val) {
this.val = val;
this.left = null;
this.right = null;
}
function BST() {
this.root = null;
}
BST.prototype._isEmpty = function() {
return this.root === null;
};
BST.prototype.insert = function(el, root) {
var n = new BSTNode(el);
if (this._isEmpty()) this.root = n;
else {
root = root || this.root;
if (el < root.val) {
if (!root.left) root.left = n;
else this.insert(el, root.left);
}
else {
if (!root.right) root.right = n;
else this.insert(el, root.right);
}
}
};
BST.prototype.preorder = function() {
var retStr = '';
function innerPreorder(curr) {
if (curr === null) return;
else {
retStr += curr.val;
innerPreorder(curr.left);
innerPreorder(curr.right);
}
}
innerPreorder(this.root);
return retStr;
};
BST.prototype.inorder = function() {
var retStr = '';
function innerInorder(curr) {
if (curr === null) return;
else {
innerInorder(curr.left);
retStr += curr.val;
innerInorder(curr.right);
}
}
innerInorder(this.root);
return retStr;
};
BST.prototype.postorder = function() {
var retStr = '';
function innerPostorder(curr) {
if (curr === null) return;
else {
innerPostorder(curr.left);
innerPostorder(curr.right);
retStr += curr.val;
}
}
innerPostorder(this.root);
return retStr;
};
BST.prototype.levelorder = function() {
var retStr = '';
var queue = [];
queue.push(this.root);
var curr;
while (queue.length > 0) {
curr = queue.shift();
retStr += curr.val;
if (curr.left) queue.push(curr.left);
if (curr.right) queue.push(curr.right);
}
return retStr;
};
BST.prototype.min = function(curr) {
curr = curr || this.root;
while (curr.left) {
curr = curr.left;
}
return curr;
};
BST.prototype.max = function(curr) {
curr = curr || this.root;
while (curr.right) {
curr = curr.right;
}
return curr;
};
BST.prototype.find = function(val) {
var curr = this.root;
while (curr) {
if (val === curr.val) return curr;
else if (val < curr.val) curr = curr.left;
else if (val > curr.val) curr = curr.right;
}
return -1;
};
BST.prototype.findParent = function(val) {
if (this.root.val === val) return false;
function innerFindParent(val, curr) {
if (!curr.left && !curr.right) return false;
if (curr.left.val === val) return curr;
else if (curr.right.val === val) return curr;
else {
var retVal;
if (curr.left) {
retVal = this.findParent(val, curr.left);
if (retVal) return retVal;
}
if (curr.right) {
retVal = this.findParent(val, curr.right);
if (retVal) return retVal;
}
return false;
}
}
return innerFindParent(val, this.root);
};
你可以写一个'custom matcher'。这个想法是您创建自己的匹配器函数,该函数可以比较特定值并且比标准 isEqual 匹配器更具体。
您可以在这里阅读更多内容:http://jasmine.github.io/2.0/custom_matcher.html
这是针对您的具体情况的 fiddle:
http://jsfiddle.net/1d9h2L2z/
//in your beforeEach you define your custom matcher:
beforeEach(function () {
this.addMatchers({
// val, left, and right
toBeAValidObjectPerDef: function () {
return (this.actual.val !== jasmine.undefined && this.actual.left !== jasmine.undefined && this.actual.right != jasmine.undefined);
}
})
});
describe('MyObject', function () {
it('is a valid object with val, left and right', function () {
// and here is how you can call it - instead of testObject you can use the one returned by your function
var testObject = new TestObject('foo', 'leftValue', 'rightValue');
expect(testObject).toBeAValidObjectPerDef();
});
});
示例:
expect(bst.find(5)).toBe(<an object>);
我如何确定它是具有以下三个属性的对象:val
、left
和 right
?
编辑:
这有效 - http://jsfiddle.net/1d9h2L2z/1/
但这不是:
describe('A Binary Search Tree', function() {
var bst;
beforeEach(function() {
this.addMatchers({
toBeANode: function () {
return this.actual.val !== undefined && this.actual.left !== undefined && this.actual.right !== undefined;
}
});
bst = new BST();
bst.insert(4);
bst.insert(2);
bst.insert(1);
bst.insert(3);
bst.insert(6);
bst.insert(5);
bst.insert(7);
// 4
// 2 6
// 1 3 5 7
});
it('can do preorder traversal', function() {
expect(bst.preorder()).toBe('4213657');
});
it('can do inorder traversal', function() {
expect(bst.inorder()).toBe('1234567');
});
it('can do postorder traversal', function() {
expect(bst.postorder()).toBe('1325764');
});
it('can do levelorder traversal', function() {
expect(bst.levelorder()).toBe('4261357');
});
it('can get the minimum', function() {
expect(bst.min()).toBeANode();
expect(bst.min().val).toBe(1);
});
it('can get the maximum', function() {
expect(bst.max()).toBeANode();
expect(bst.max().val).toBe(7);
});
it('can find', function() {
expect(bst.find(5)).toBeANode();
expect(bst.find(5).val).toBe(5);
expect(bst.find(10)).toBe(-1);
});
it('can findParent', function() {
expect(bst.findParent(5)).toBeANode();
expect(bst.findParent(5).val).toBe(6);
expect(bst.findParent(8)).toBe(-1); // nonexistant node
expect(bst.findParent(4)).toBe(-1); // root
});
it('can remove a leaf node', function() {
bst.remove(7);
expect(bst.inorder()).toBe('123456');
});
it('can remove a node with one child', function() {
bst.insert(8);
bst.remove(7);
expect(bst.inorder()).toBe('1234568');
});
it('can remove a node with two children', function() {
bst.insert(2.1);
bst.remove(2);
expect(bst.inorder()).toBe('12.134567'); // right subtree has a left subtree
bst.insert(8);
bst.remove(6);
expect(bst.inorder()).toBe('12.134578'); // right subtree doesn't have a left subtree
});
// add AVL stuff
});
英国夏令时:
function BSTNode(val) {
this.val = val;
this.left = null;
this.right = null;
}
function BST() {
this.root = null;
}
BST.prototype._isEmpty = function() {
return this.root === null;
};
BST.prototype.insert = function(el, root) {
var n = new BSTNode(el);
if (this._isEmpty()) this.root = n;
else {
root = root || this.root;
if (el < root.val) {
if (!root.left) root.left = n;
else this.insert(el, root.left);
}
else {
if (!root.right) root.right = n;
else this.insert(el, root.right);
}
}
};
BST.prototype.preorder = function() {
var retStr = '';
function innerPreorder(curr) {
if (curr === null) return;
else {
retStr += curr.val;
innerPreorder(curr.left);
innerPreorder(curr.right);
}
}
innerPreorder(this.root);
return retStr;
};
BST.prototype.inorder = function() {
var retStr = '';
function innerInorder(curr) {
if (curr === null) return;
else {
innerInorder(curr.left);
retStr += curr.val;
innerInorder(curr.right);
}
}
innerInorder(this.root);
return retStr;
};
BST.prototype.postorder = function() {
var retStr = '';
function innerPostorder(curr) {
if (curr === null) return;
else {
innerPostorder(curr.left);
innerPostorder(curr.right);
retStr += curr.val;
}
}
innerPostorder(this.root);
return retStr;
};
BST.prototype.levelorder = function() {
var retStr = '';
var queue = [];
queue.push(this.root);
var curr;
while (queue.length > 0) {
curr = queue.shift();
retStr += curr.val;
if (curr.left) queue.push(curr.left);
if (curr.right) queue.push(curr.right);
}
return retStr;
};
BST.prototype.min = function(curr) {
curr = curr || this.root;
while (curr.left) {
curr = curr.left;
}
return curr;
};
BST.prototype.max = function(curr) {
curr = curr || this.root;
while (curr.right) {
curr = curr.right;
}
return curr;
};
BST.prototype.find = function(val) {
var curr = this.root;
while (curr) {
if (val === curr.val) return curr;
else if (val < curr.val) curr = curr.left;
else if (val > curr.val) curr = curr.right;
}
return -1;
};
BST.prototype.findParent = function(val) {
if (this.root.val === val) return false;
function innerFindParent(val, curr) {
if (!curr.left && !curr.right) return false;
if (curr.left.val === val) return curr;
else if (curr.right.val === val) return curr;
else {
var retVal;
if (curr.left) {
retVal = this.findParent(val, curr.left);
if (retVal) return retVal;
}
if (curr.right) {
retVal = this.findParent(val, curr.right);
if (retVal) return retVal;
}
return false;
}
}
return innerFindParent(val, this.root);
};
你可以写一个'custom matcher'。这个想法是您创建自己的匹配器函数,该函数可以比较特定值并且比标准 isEqual 匹配器更具体。 您可以在这里阅读更多内容:http://jasmine.github.io/2.0/custom_matcher.html
这是针对您的具体情况的 fiddle: http://jsfiddle.net/1d9h2L2z/
//in your beforeEach you define your custom matcher:
beforeEach(function () {
this.addMatchers({
// val, left, and right
toBeAValidObjectPerDef: function () {
return (this.actual.val !== jasmine.undefined && this.actual.left !== jasmine.undefined && this.actual.right != jasmine.undefined);
}
})
});
describe('MyObject', function () {
it('is a valid object with val, left and right', function () {
// and here is how you can call it - instead of testObject you can use the one returned by your function
var testObject = new TestObject('foo', 'leftValue', 'rightValue');
expect(testObject).toBeAValidObjectPerDef();
});
});