/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html version: 3.3.0 build: 3167 */ YUI.add('test',function(Y){Y.namespace("Test");Y.Test.Case=function(template){this._should={};for(var prop in template){this[prop]=template[prop];} if(!Y.Lang.isString(this.name)){this.name="testCase"+Y.guid();}};Y.Test.Case.prototype={resume:function(segment){Y.Test.Runner.resume(segment);},wait:function(segment,delay){var args=arguments;if(Y.Lang.isFunction(args[0])){throw new Y.Test.Wait(args[0],args[1]);}else{throw new Y.Test.Wait(function(){Y.Assert.fail("Timeout: wait() called but resume() never called.");},(Y.Lang.isNumber(args[0])?args[0]:10000));}},setUp:function(){},tearDown:function(){}};Y.Test.Wait=function(segment,delay){this.segment=(Y.Lang.isFunction(segment)?segment:null);this.delay=(Y.Lang.isNumber(delay)?delay:0);};Y.namespace("Test");Y.Test.Suite=function(data){this.name="";this.items=[];if(Y.Lang.isString(data)){this.name=data;}else if(Y.Lang.isObject(data)){Y.mix(this,data,true);} if(this.name===""){this.name="testSuite"+Y.guid();}};Y.Test.Suite.prototype={add:function(testObject){if(testObject instanceof Y.Test.Suite||testObject instanceof Y.Test.Case){this.items.push(testObject);} return this;},setUp:function(){},tearDown:function(){}};Y.Test.Runner=(function(){function TestNode(testObject){this.testObject=testObject;this.firstChild=null;this.lastChild=null;this.parent=null;this.next=null;this.results={passed:0,failed:0,total:0,ignored:0,duration:0};if(testObject instanceof Y.Test.Suite){this.results.type="testsuite";this.results.name=testObject.name;}else if(testObject instanceof Y.Test.Case){this.results.type="testcase";this.results.name=testObject.name;}} TestNode.prototype={appendChild:function(testObject){var node=new TestNode(testObject);if(this.firstChild===null){this.firstChild=this.lastChild=node;}else{this.lastChild.next=node;this.lastChild=node;} node.parent=this;return node;}};function TestRunner(){TestRunner.superclass.constructor.apply(this,arguments);this.masterSuite=new Y.Test.Suite("yuitests"+(new Date()).getTime());this._cur=null;this._root=null;this._log=true;this._waiting=false;this._running=false;this._lastResults=null;var events=[this.TEST_CASE_BEGIN_EVENT,this.TEST_CASE_COMPLETE_EVENT,this.TEST_SUITE_BEGIN_EVENT,this.TEST_SUITE_COMPLETE_EVENT,this.TEST_PASS_EVENT,this.TEST_FAIL_EVENT,this.TEST_IGNORE_EVENT,this.COMPLETE_EVENT,this.BEGIN_EVENT];for(var i=0;i-1&&prop.indexOf(" ")>-1))&&Y.Lang.isFunction(testCase[prop])){node.appendChild(prop);}}},_addTestSuiteToTestTree:function(parentNode,testSuite){var node=parentNode.appendChild(testSuite);for(var i=0;i0){return Y.Lang.substitute(customMessage,{message:defaultMessage});}else{return defaultMessage;}},_getCount:function(){return this._asserts;},_increment:function(){this._asserts++;},_reset:function(){this._asserts=0;},fail:function(message){throw new Y.Assert.Error(Y.Assert._formatMessage(message,"Test force-failed."));},areEqual:function(expected,actual,message){Y.Assert._increment();if(expected!=actual){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Values should be equal."),expected,actual);}},areNotEqual:function(unexpected,actual,message){Y.Assert._increment();if(unexpected==actual){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Values should not be equal."),unexpected);}},areNotSame:function(unexpected,actual,message){Y.Assert._increment();if(unexpected===actual){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Values should not be the same."),unexpected);}},areSame:function(expected,actual,message){Y.Assert._increment();if(expected!==actual){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Values should be the same."),expected,actual);}},isFalse:function(actual,message){Y.Assert._increment();if(false!==actual){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value should be false."),false,actual);}},isTrue:function(actual,message){Y.Assert._increment();if(true!==actual){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value should be true."),true,actual);}},isNaN:function(actual,message){Y.Assert._increment();if(!isNaN(actual)){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value should be NaN."),NaN,actual);}},isNotNaN:function(actual,message){Y.Assert._increment();if(isNaN(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Values should not be NaN."),NaN);}},isNotNull:function(actual,message){Y.Assert._increment();if(Y.Lang.isNull(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Values should not be null."),null);}},isNotUndefined:function(actual,message){Y.Assert._increment();if(Y.Lang.isUndefined(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should not be undefined."),undefined);}},isNull:function(actual,message){Y.Assert._increment();if(!Y.Lang.isNull(actual)){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value should be null."),null,actual);}},isUndefined:function(actual,message){Y.Assert._increment();if(!Y.Lang.isUndefined(actual)){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value should be undefined."),undefined,actual);}},isArray:function(actual,message){Y.Assert._increment();if(!Y.Lang.isArray(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should be an array."),actual);}},isBoolean:function(actual,message){Y.Assert._increment();if(!Y.Lang.isBoolean(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should be a Boolean."),actual);}},isFunction:function(actual,message){Y.Assert._increment();if(!Y.Lang.isFunction(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should be a function."),actual);}},isInstanceOf:function(expected,actual,message){Y.Assert._increment();if(!(actual instanceof expected)){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value isn't an instance of expected type."),expected,actual);}},isNumber:function(actual,message){Y.Assert._increment();if(!Y.Lang.isNumber(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should be a number."),actual);}},isObject:function(actual,message){Y.Assert._increment();if(!Y.Lang.isObject(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should be an object."),actual);}},isString:function(actual,message){Y.Assert._increment();if(!Y.Lang.isString(actual)){throw new Y.Assert.UnexpectedValue(Y.Assert._formatMessage(message,"Value should be a string."),actual);}},isTypeOf:function(expectedType,actualValue,message){Y.Assert._increment();if(typeof actualValue!=expectedType){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Value should be of type "+expectedType+"."),expected,typeof actualValue);}}};Y.assert=function(condition,message){Y.Assert._increment();if(!condition){throw new Y.Assert.Error(Y.Assert._formatMessage(message,"Assertion failed."));}};Y.fail=Y.Assert.fail;Y.Assert.Error=function(message){arguments.callee.superclass.constructor.call(this,message);this.message=message;this.name="Assert Error";};Y.extend(Y.Assert.Error,Error,{getMessage:function(){return this.message;},toString:function(){return this.name+": "+this.getMessage();},valueOf:function(){return this.toString();}});Y.Assert.ComparisonFailure=function(message,expected,actual){arguments.callee.superclass.constructor.call(this,message);this.expected=expected;this.actual=actual;this.name="ComparisonFailure";};Y.extend(Y.Assert.ComparisonFailure,Y.Assert.Error,{getMessage:function(){return this.message+"\nExpected: "+this.expected+" ("+(typeof this.expected)+")"+"\nActual: "+this.actual+" ("+(typeof this.actual)+")";}});Y.Assert.UnexpectedValue=function(message,unexpected){arguments.callee.superclass.constructor.call(this,message);this.unexpected=unexpected;this.name="UnexpectedValue";};Y.extend(Y.Assert.UnexpectedValue,Y.Assert.Error,{getMessage:function(){return this.message+"\nUnexpected: "+this.unexpected+" ("+(typeof this.unexpected)+") ";}});Y.Assert.ShouldFail=function(message){arguments.callee.superclass.constructor.call(this,message||"This test should fail but didn't.");this.name="ShouldFail";};Y.extend(Y.Assert.ShouldFail,Y.Assert.Error);Y.Assert.ShouldError=function(message){arguments.callee.superclass.constructor.call(this,message||"This test should have thrown an error but didn't.");this.name="ShouldError";};Y.extend(Y.Assert.ShouldError,Y.Assert.Error);Y.Assert.UnexpectedError=function(cause){arguments.callee.superclass.constructor.call(this,"Unexpected error: "+cause.message);this.cause=cause;this.name="UnexpectedError";this.stack=cause.stack;};Y.extend(Y.Assert.UnexpectedError,Y.Assert.Error);Y.ArrayAssert={contains:function(needle,haystack,message){Y.Assert._increment();if(Y.Array.indexOf(haystack,needle)==-1){Y.Assert.fail(Y.Assert._formatMessage(message,"Value "+needle+" ("+(typeof needle)+") not found in array ["+haystack+"]."));}},containsItems:function(needles,haystack,message){Y.Assert._increment();for(var i=0;i-1){Y.Assert.fail(Y.Assert._formatMessage(message,"Value found in array ["+haystack+"]."));}},doesNotContainItems:function(needles,haystack,message){Y.Assert._increment();for(var i=0;i-1){Y.Assert.fail(Y.Assert._formatMessage(message,"Value found in array ["+haystack+"]."));}}},doesNotContainMatch:function(matcher,haystack,message){Y.Assert._increment();if(typeof matcher!="function"){throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");} if(Y.Array.some(haystack,matcher)){Y.Assert.fail(Y.Assert._formatMessage(message,"Value found in array ["+haystack+"]."));}},indexOf:function(needle,haystack,index,message){Y.Assert._increment();for(var i=0;i0){Y.Assert.fail(Y.Assert._formatMessage(message,"Array should be empty."));}},isNotEmpty:function(actual,message){Y.Assert._increment();if(actual.length===0){Y.Assert.fail(Y.Assert._formatMessage(message,"Array should not be empty."));}},itemsAreSame:function(expected,actual,message){Y.Assert._increment();if(expected.length!=actual.length){Y.Assert.fail(Y.Assert._formatMessage(message,"Array should have a length of "+expected.length+" but has a length of "+actual.length));} for(var i=0;i=0;i--){if(haystack[i]===needle){if(index!=i){Y.Assert.fail(Y.Assert._formatMessage(message,"Value exists at index "+i+" but should be at index "+index+"."));} return;}} Y.Assert.fail(Y.Assert._formatMessage(message,"Value doesn't exist in array."));}};Y.ObjectAssert={areEqual:function(expected,actual,message){Y.Assert._increment();Y.Object.each(expected,function(value,name){if(expected[name]!=actual[name]){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,"Values should be equal for property "+name),expected[name],actual[name]);}});},hasKey:function(propertyName,object,message){Y.Assert._increment();if(!(propertyName in object)){Y.fail(Y.Assert._formatMessage(message,"Property '"+propertyName+"' not found on object."));}},hasKeys:function(properties,object,message){Y.Assert._increment();for(var i=0;i0){Y.fail(Y.Assert._formatMessage(message,"Object owns "+keys.length+" properties but should own none."));}}};Y.DateAssert={datesAreEqual:function(expected,actual,message){Y.Assert._increment();if(expected instanceof Date&&actual instanceof Date){var msg="";if(expected.getFullYear()!=actual.getFullYear()){msg="Years should be equal.";} if(expected.getMonth()!=actual.getMonth()){msg="Months should be equal.";} if(expected.getDate()!=actual.getDate()){msg="Days of month should be equal.";} if(msg.length){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,msg),expected,actual);}}else{throw new TypeError("Y.Assert.datesAreEqual(): Expected and actual values must be Date objects.");}},timesAreEqual:function(expected,actual,message){Y.Assert._increment();if(expected instanceof Date&&actual instanceof Date){var msg="";if(expected.getHours()!=actual.getHours()){msg="Hours should be equal.";} if(expected.getMinutes()!=actual.getMinutes()){msg="Minutes should be equal.";} if(expected.getSeconds()!=actual.getSeconds()){msg="Seconds should be equal.";} if(msg.length){throw new Y.Assert.ComparisonFailure(Y.Assert._formatMessage(message,msg),expected,actual);}}else{throw new TypeError("DateY.AsserttimesAreEqual(): Expected and actual values must be Date objects.");}}};Y.namespace("Test.Format");function xmlEscape(text){return text.replace(/[<>"'&]/g,function(value){switch(value){case"<":return"<";case">":return">";case"\"":return""";case"'":return"'";case"&":return"&";}});} Y.Test.Format.JSON=function(results){return Y.JSON.stringify(results);};Y.Test.Format.XML=function(results){function serializeToXML(results){var l=Y.Lang,xml="<"+results.type+" name=\""+xmlEscape(results.name)+"\"";if(l.isNumber(results.duration)){xml+=" duration=\""+results.duration+"\"";} if(results.type=="test"){xml+=" result=\""+results.result+"\" message=\""+xmlEscape(results.message)+"\">";}else{xml+=" passed=\""+results.passed+"\" failed=\""+results.failed+"\" ignored=\""+results.ignored+"\" total=\""+results.total+"\">";Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){xml+=serializeToXML(value);}});} xml+="";return xml;} return""+serializeToXML(results);};Y.Test.Format.JUnitXML=function(results){function serializeToJUnitXML(results){var l=Y.Lang,xml="";switch(results.type){case"test":if(results.result!="ignore"){xml="";if(results.result=="fail"){xml+="";} xml+="";} break;case"testcase":xml="";Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){xml+=serializeToJUnitXML(value);}});xml+="";break;case"testsuite":Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){xml+=serializeToJUnitXML(value);}});break;case"report":xml="";Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){xml+=serializeToJUnitXML(value);}});xml+="";} return xml;} return""+serializeToJUnitXML(results);};Y.Test.Format.TAP=function(results){var currentTestNum=1;function serializeToTAP(results){var l=Y.Lang,text="";switch(results.type){case"test":if(results.result!="ignore"){text="ok "+(currentTestNum++)+" - "+results.name;if(results.result=="fail"){text="not "+text+" - "+results.message;} text+="\n";}else{text="#Ignored test "+results.name+"\n";} break;case"testcase":text="#Begin testcase "+results.name+"("+results.failed+" failed of "+results.total+")\n";Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){text+=serializeToTAP(value);}});text+="#End testcase "+results.name+"\n";break;case"testsuite":text="#Begin testsuite "+results.name+"("+results.failed+" failed of "+results.total+")\n";Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){text+=serializeToTAP(value);}});text+="#End testsuite "+results.name+"\n";break;case"report":Y.Object.each(results,function(value){if(l.isObject(value)&&!l.isArray(value)){text+=serializeToTAP(value);}});} return text;} return"1.."+results.total+"\n"+serializeToTAP(results);};Y.namespace("Coverage.Format");Y.Coverage.Format.JSON=function(coverage){return Y.JSON.stringify(coverage);};Y.Coverage.Format.XdebugJSON=function(coverage){var report={};Y.Object.each(coverage,function(value,name){report[name]=coverage[name].lines;});return Y.JSON.stringify(report);};Y.namespace("Test");Y.Test.Reporter=function(url,format){this.url=url;this.format=format||Y.Test.Format.XML;this._fields=new Object();this._form=null;this._iframe=null;};Y.Test.Reporter.prototype={constructor:Y.Test.Reporter,addField:function(name,value){this._fields[name]=value;},clearFields:function(){this._fields=new Object();},destroy:function(){if(this._form){this._form.parentNode.removeChild(this._form);this._form=null;} if(this._iframe){this._iframe.parentNode.removeChild(this._iframe);this._iframe=null;} this._fields=null;},report:function(results){if(!this._form){this._form=document.createElement("form");this._form.method="post";this._form.style.visibility="hidden";this._form.style.position="absolute";this._form.style.top=0;document.body.appendChild(this._form);var iframeContainer=document.createElement("div");iframeContainer.innerHTML="";this._iframe=iframeContainer.firstChild;this._iframe.src="javascript:false";this._iframe.style.visibility="hidden";this._iframe.style.position="absolute";this._iframe.style.top=0;document.body.appendChild(this._iframe);this._form.target="yuiTestTarget";} this._form.action=this.url;while(this._form.hasChildNodes()){this._form.removeChild(this._form.lastChild);} this._fields.results=this.format(results);this._fields.useragent=navigator.userAgent;this._fields.timestamp=(new Date()).toLocaleString();Y.Object.each(this._fields,function(value,prop){if(typeof value!="function"){var input=document.createElement("input");input.type="hidden";input.name=prop;input.value=value;this._form.appendChild(input);}},this);delete this._fields.results;delete this._fields.useragent;delete this._fields.timestamp;if(arguments[1]!==false){this._form.submit();}}};Y.Mock=function(template){template=template||{};var mock=null;try{mock=Y.Object(template);}catch(ex){mock={};Y.log("Couldn't create mock with prototype.","warn","Mock");} Y.Object.each(template,function(name){if(Y.Lang.isFunction(template[name])){mock[name]=function(){Y.Assert.fail("Method "+name+"() was called but was not expected to be.");};}});return mock;};Y.Mock.expect=function(mock,expectation){if(!mock.__expectations){mock.__expectations={};} if(expectation.method){var name=expectation.method,args=expectation.args||expectation.arguments||[],result=expectation.returns,callCount=Y.Lang.isNumber(expectation.callCount)?expectation.callCount:1,error=expectation.error,run=expectation.run||function(){};mock.__expectations[name]=expectation;expectation.callCount=callCount;expectation.actualCallCount=0;Y.Array.each(args,function(arg,i,array){if(!(array[i]instanceof Y.Mock.Value)){array[i]=Y.Mock.Value(Y.Assert.areSame,[arg],"Argument "+i+" of "+name+"() is incorrect.");}});if(callCount>0){mock[name]=function(){try{expectation.actualCallCount++;Y.Assert.areEqual(args.length,arguments.length,"Method "+name+"() passed incorrect number of arguments.");for(var i=0,len=args.length;i