Commit 54fb4c03 54fb4c03bb7184cce4520437243b317dec78263b by Nicolas Perriault

Merge pull request #619 from mickaelandrieu/master

Introduced Tester.assertInstanceOf method, refs #602
2 parents eb4be25d 81c22d71
......@@ -450,9 +450,9 @@ Asserts that the provided input is of the given type::
``assertInstanceOf()``
-------------------------------------------------------------------------------
**Signature:** ``assertInstanceOf(mixed input, String className[, String message])``
**Signature:** ``assertInstanceOf(mixed input, Function constructor[, String message])``
Asserts that the provided input is of the given className::
Asserts that the provided input is of the given constructor::
function Cow() {
this.moo = function moo() {
......@@ -461,8 +461,8 @@ Asserts that the provided input is of the given className::
}
casper.test.begin('assertInstanceOf() tests', 2, function suite(test) {
var daisy = new Cow();
test.assertInstanceOf(daisy, "Cow", "Ok, daisy is a cow.");
test.assertInstanceOf(["moo", "boo"], "Array", "We can test for arrays too!");
test.assertInstanceOf(daisy, Cow, "Ok, daisy is a cow.");
test.assertInstanceOf(["moo", "boo"], Array, "We can test for arrays too!");
test.done();
});
......
......@@ -24,6 +24,13 @@ Usage is pretty much straightforward::
Provides a better ``typeof`` operator equivalent, eg. able to retrieve the ``Array`` type.
``betterInstanceOf()``
-------------------------------------------------------------------------------
**Signature:** ``betterInstanceOf(input, constructor)``
Provides a better ``instanceof`` operator equivalent, is able to retrieve the ``Array`` instance or to deal with inheritance.
.. index:: dump, Serialization, Debugging, JSON
.. _utils_dump:
......
......@@ -840,24 +840,24 @@ Tester.prototype.assertType = function assertType(subject, type, message) {
};
/**
* Asserts that the provided subject is of the given class name.
* Asserts that the provided subject has the provided constructor in its prototype hierarchy.
*
* @param mixed subject The value to test
* @param string className The className
* @param Function constructor The javascript type name
* @param String message Test description
* @return Object An assertion result object
*/
Tester.prototype.assertInstanceOf = function assertInstanceOf(subject, className, message) {
Tester.prototype.assertInstanceOf = function assertInstanceOf(subject, constructor, message) {
"use strict";
if (utils.betterTypeOf(subject.constructor) !== "function") {
if (utils.betterTypeOf(constructor) !== "function") {
throw new CasperError('Subject is null or undefined.');
}
return this.assert(utils.equals(subject.constructor.name, className), message, {
return this.assert(utils.betterInstanceOf(subject, constructor), message, {
type: "assertInstanceOf",
standard: f('Subject is an instance of: "%s"', subject.constructor.name),
standard: f('Subject is instance of: "%s"', constructor.name),
values: {
subject: subject,
className: className,
constructorName: constructor.name,
}
});
};
......
......@@ -71,6 +71,33 @@ function betterTypeOf(input) {
exports.betterTypeOf = betterTypeOf;
/**
* Provides a better instanceof operator, capable of checking against the full object prototype hierarchy.
*
* @param mixed input
* @param function constructor
* @return String
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
*/
function betterInstanceOf(input, constructor) {
"use strict";
/*jshint eqnull:true, eqeqeq:false */
while (input != null) {
if (input == constructor.prototype) {
return true;
}
if (typeof input == 'xml') {
return constructor.prototype == document.prototype;
}
if (typeof input == 'undefined') {
return false;
}
input = input.__proto__;
}
return false;
}
exports.betterInstanceOf = betterInstanceOf;
/**
* Cleans a passed URL.
*
* @param String url An HTTP URL
......
......@@ -2,7 +2,7 @@
/*jshint strict:false, maxstatements:99*/
var fs = require('fs');
casper.test.begin('Common assertions tests', 50, function(test) {
casper.test.begin('Common assertions tests', 46, function(test) {
casper.start('tests/site/index.html', function() {
test.assertTextExists('form', 'Tester.assertTextExists() checks that page body contains text');
test.assertTextExist('form', 'Tester.assertTextExist() checks that page body contains text [alias]');
......@@ -60,13 +60,7 @@ casper.test.begin('Common assertions tests', 50, function(test) {
test.assertTitleMatch(/test index/, 'Tester.assertTitleMatch() works as expected');
test.assertTitleMatches(/test index/, 'Tester.assertTitleMatches() works as expected [alias]');
test.assertType("plop", "string", "Tester.assertType() works as expected");
// we need a class and an instance of this class
function Cow(){} var daisy = new Cow();
test.assertInstanceOf(12, "Number", "Tester.assertInstanceOf() works as expected");
test.assertInstanceOf("Boo", "String", "Tester.assertInstanceOf() works as expected");
test.assertInstanceOf(["moo", "bar"], "Array", "Tester.assertInstanceOf() works as expected")
test.assertInstanceOf(true, "Boolean", "Test.assertInstanceOf() works as expected");
test.assertInstanceOf(daisy, "Cow", "Tester.assertInstanceOf() works as expected");
test.assertInstanceOf("plop", String, "Tester.assertInstanceOf() works as expected");
test.assertUrlMatch(/index\.html$/, "Tester.assertUrlMatch() works as expected");
test.assertUrlMatches(/index\.html$/, "Tester.assertUrlMatches() works as expected [alias]");
test.assertVisible('img', 'Tester.assertVisible() works as expected');
......
......@@ -24,6 +24,34 @@ casper.test.begin('utils.betterTypeOf() tests', 10, function(test) {
test.done();
});
casper.test.begin('utils.betterInstanceOf() tests', 13, function(test) {
/*global XMLDocument*/
// need two objects to test inheritance
function Cow(){} var daisy = new Cow();
function SuperCow(){} SuperCow.prototype = new Cow(); var superDaisy = new SuperCow();
var date = new Date(); var regex = new RegExp(); var xmlDoc = document.implementation.createDocument("<y>", "x");
var testCases = [
{subject: 1, fn: Number, expected: true},
{subject: '1', fn: String, expected: true},
{subject: {}, fn: Object, expected: true},
{subject: [], fn: Array, expected: true},
{subject: undefined, fn: Array, expected: false},
{subject: null, fn: Array, expected: false},
{subject: function(){}, fn: Function, expected: true},
{subject: date, fn: Date, expected: true},
{subject: regex, fn: RegExp, expected: true},
{subject: xmlDoc, fn: XMLDocument, expected: true},
{subject: daisy, fn: Cow, expected: true},
{subject: superDaisy, fn: SuperCow, expected: true},
{subject: superDaisy, fn: Cow, expected: true}
];
testCases.forEach(function(testCase) {
test.assertEquals(utils.betterInstanceOf(testCase.subject, testCase.fn), testCase.expected,
utils.format('betterInstanceOf() detects expected constructor "%s"', testCase.fn.name));
});
test.done();
});
casper.test.begin('utils.cleanUrl() tests', 11, function(test) {
var testCases = {
'http://google.com/': 'http://google.com/',
......