/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

CKPACKAGER.load( 'ckpackager.includes.scriptcompressor' );

(function()
{
	// These are tests automatically generated later in this file. The following array contain the list of tests to be executed.
	var autoTests =
	[
		[	"var a=1;" ],

		[	"var a=1;var b=2;",
			"var a=1,b=2;" ],

		[	"var var1 = var1, var2 = var1;",
			"var a=var1,b=a;" ],

		[	"function Test( param ) { var myVar = 1; return myVar + param; }; Test( 'Sample' );",
			"function a(b){var c=1;return c+b;};a('Sample');" ],

		[	"var Test; ( Test = function( rtl ){ return rtl + 'y'; } )(); Test( 'x' );",
		 	"var a;(a=function(b){return b+'y';})();a('x');" ],

		[	"var result = 6 * 10 / 3 + 4;",
			"var a=24;" ],

		[	"var sum = 1 + 2 + Math['P' + String('I')] - Math.E;",
			"var a=3+Math['P'+String('I')]-Math.E;" ],

		[	"var sum = ( a + b ) - ( c * ( d - e ) );",
			"var a=a+b-c*(d-e);" ],

		[	"var str = '\"Tiger\", \"Lion\" ' + \"& 'Cat'\";",
			"var a='\"Tiger\", \"Lion\" & \\'Cat\\'';" ],

		[	"var str = \"'Tiger', 'Lion' \" + '& \"Cat\"';",
			"var a=\"'Tiger', 'Lion' & \\\"Cat\\\"\";" ],

		[	"var funs = fun() + fun1( a ) + fun2( a + b, c );",
			"var a=fun()+fun1(a)+fun2(a+b,c);" ],

		[	"var a,b,c;if(a)go();" ],

		[	"if(a){go1();go2();}" ],

		[	"if(a){go();}",
			"if(a)go();" ],

		[	"if((a=1))go();",
			"if(a=1)go();" ],

		[	"if(a){if(b)go();}",
			"if(a)if(b)go();" ],

		[	"while(a=1){go();break;}" ],

		[	"while(a=1)go();" ],

		[	"while(a=1){go();}",
			"while(a=1)go();" ],

		[	"while(a=1){go1();continue;go2();}",
			"while(a=1){go1();}" ],

		[	"while(a=1){go1();continue;go2();function go1(){go();};}",
			"while(a=1){a();function a(){go();};}" ],

		[	"do{go1();go2();}while(e)" ],

		[	"do{go();}while(e)",
			"do go();while(e)" ],

		[	"for(var i=0,len=ar.length;i<len;i++){go1();go2();}",
			"for(var a=0,b=ar.length;a<b;a++){go1();go2();}" ],

		[	"for(var i=0,len=ar.length;i<len;i++){go();}",
			"for(var a=0,b=ar.length;a<b;a++)go();" ],

		[	"for(var o in obj.prop){go1();go2();}",
			"for(var a in obj.prop){go1();go2();}" ],

		[	"for(var o in obj.prop){go()}",
			"for(var a in obj.prop)go();" ],

		[	"for(o in obj.prop)go();" ],

		[	"for(;;i++){}" ],

		[	"for(;;){}" ],

		[	"while(true){go();}",
			"for(;;)go();" ],

		[	"for(;a;){}",
			"while(a){}" ],

		[	"for(;q;++q){}" ],

		[	"for(var a=b.length-1;a>=0;a--){}" ],

		[	"if(true){go();}",
			"go();" ],

		[	"if(c==false)go();" ],

		[	"if(c===true)go();" ],

		[	"if(e)go1();else go2();" ],

		[	"a&b;a&&b;" ],

		[	"a+=10;a&=10;" ],

		[	"a=b-14;a=b+1;" ],

		[	"a>>b;a<<b;a>>>b;" ],

		[	"a=a+2;b=b+2;c=c/3;d=d*4;",
			"a+=2;b+=2;c/=3;d*=4;" ],

		[	"typeof v=='string';" ],

		[	"delete a.b.c;" ],

		[	"new OBJ.clazz('Test',15);" ],

		[	"new clazz();" ],

		[	"var a=new Array();",
			"var a=[];" ],

		[	"var a=new Array(2);" ],

		[	"var a=new Array(2,'fred');",
			"var a=[2,'fred'];" ],

		[	"var a=new Array(b);" ],

		[	"var a=new Array(b+1);" ],

		[	"var a=new Object();",
			"var a={};" ],

		[	"var a=new Object(2);" ],

		[	"if(a)b();else if(c)d();else e();" ],

		[	"A.B.C=3;" ],

		[	"A.B['C']=3;",
			"A.B.C=3;" ],

		[	"A.B['C'+a]=3;" ],

		[	"var o={a:{b:function(){o;}}};",
			"var a={a:{b:function(){a;}}};" ],

		[	"var a=[1,2,'Fred'];" ],

		[	"function(A,B,C){var D=A+B,E=C+1;return D+E;}",
			"function(a,b,c){var d=a+b,e=c+1;return d+e;}" ],

		[	"function(){return;go();}",
			"function(){}" ],

		[	"function(){go();return;}",
			"function(){go();}" ],

		[	"function(){function A(B,C){var D=B+C;return D;};}",
			"function(){function a(b,c){var d=b+c;return d;};}" ],

		[	"function(){}" ],

		[	"switch(A){case 'A':go1();break;case 'B':go2();default:go3();}" ],

		[	"var a,x,y,r=10;with(Math){a=PI*r*r;x=r*cos(PI);y=r*sin(E/2);}",
			"var a,b,c,d=10;with(Math){a=PI*d*d;b=d*cos(PI);c=d*sin(E/2);}" ],

		[	"(function(A){go(A);})('Test');",
			"(function(a){go(a);})('Test');" ],

		[	"x=a?b:c;" ],

		[	"a=++c+d-- - --d;" ],

		[	"if(a==b)c++;else d++;" ],

		[	"a=/AA\s*/gi;" ],

		[	"is=/AA\s*/gi.test('Test');" ],

		[	"s='Test1 ' +\n'& \\\nTest2';",
			"s='Test1 & Test2';" ],

		[	"x=null;" ],

		[	"try{go();}catch(e){throw 'Test';}",
			"try{go();}catch(a){throw 'Test';}" ],

		[	"try{go();}finally{go2();}" ],

		[	"try{go();}catch(e){throw e;}finally{go2();}",
			"try{go();}catch(a){throw a;}finally{go2();}" ],

		[	"a=-c;" ],

		[	"b=+c;" ],

		[	"a=!(b+c);" ],

		[	"typeof a+b;" ],

		[	"x+=y;x-=y;x*=y;x/=y;x%=y;x<<=y;x>>=y;x>>>=y;x&=y;x^=y;x|=y;" ],

		[	"x=void(0);" ],

		[	"x=\"\\nFred\\t\\tKami's \\\\Edu \\r\\n\";" ],

		[	"'\\ufeff\\xa0\\x1b';" ],

		[	"function(){this.a();this.b();this.c();}" ],

		[	"function(){this.a();this.b();this.c();this.d();}",
			"function(){var a=this;a.a();a.b();a.c();a.d();}" ],

		[	"ie=/*@cc_on!@*/false;" ],

		[	"(this.a||(this.a={})).b={};" ],

		[	"while(a){if(b)continue;go();}" ],

		[	"function(a){if(b)return;go();}" ],

		[	"a||(a=b);"],

		[	"obj instanceof claz;" ],

		[	"o={prop1:1,1:'Fred','var':'Reserved','#':'XYZ','do-it':1};" ],

		[	"o={'false':1,'true':1,'null':1};" ],

		[	"o['#']['var']=1;" ],

		[	"o['true']['false']['null']=1;" ],

		[	"a.b+=1;" ],

		[	"(a?b:c).go();" ],

		[	"for(i=0;i<1;i++){}" ],

		[	"a in b;" ],

		[	"o={'':1};" ],

		[	"with(o){a=b;}" ],

		[	"o={'\\b':'\\\\b','\\t':'\\\\t','\\n':'\\\\n','\\f':'\\\\f','\\r':'\\\\r','\"':'\\\\\"','\\\\':'\\\\\\\\'};" ],

		[	"if(a){}else{}" ],

		[	"a=b+c*1;",
			"a=b+ +c;" ],

		[	"function(){\n// PACKAGER_RENAME( CKEDITOR )\nCKEDITOR.env={ie:true};\n// PACKAGER_RENAME( CKEDITOR.env )\n// PACKAGER_RENAME( CKEDITOR.env.ie )\nif (CKEDITOR&&CKEDITOR.env&&CKEDITOR.env.ie){go();}}",
			"function(){var a=CKEDITOR;a.env={ie:true};var b=a.env;var c=b.ie;if(a&&b&&c)go();}" ],

		[	"x=a+(b+c);" ],

		[	"x=a+b+c;" ],

		[	"x=(a+b)+c;",
			"x=a+b+c;" ],

		[	"x=a&&b&&c;" ],

		[	"if(a){if(B)doB();}else if(c)doC();" ],

		[	"var a={'0':'0'};",
			"var a={0:'0'};" ],

		[	"var a={'1':'1'};",
			"var a={1:'1'};" ],

		[	"var a={'0123':'0123'};",
			"var a={'0123':'0123'};" ],

		[	"var a={'123':'123'};",
			"var a={123:'123'};" ],

		[	"var a=(b)?c:d;",
			"var a=b?c:d;" ],

		[	"var a=(b=c)?d:e;" ],

		[	"if(a){for(;;){if(B){doB();}}}else{doC();}",
			"if(a)for(;;){if(B)doB();}else doC();" ],

		[	"a((1,2),3);" ],

		[	"(1,2)+3;" ],

		[	"3+(1,2);" ],

		[	"(1,2);", "1,2;" ],

		[	"var a=(1,2,3,4);" ],

		[	"a=(1,2,3,4);" ],

		[	"var A=function B(){var C=1;B();};", "var a=function c(){var b=1;c();};" ],

		[	"var A={foo:function C(){}};", "var a={foo:function b(){}};" ],

		[	"call(function A(){});", "call(function a(){});" ],

		[	"do{}while(1)" ],

		[	"do{}while(1)A();", "do{}while(1);A();" ]
	];

	var tests =
	{
	};

	////////////////////////////////////////////////

	function assertEquals( expected, actual )
	{
		if ( expected != actual )
		{
			var error =
			{
				expected : expected,
				actual : actual
			}

			throw error;
		}
	}

	// Create the auto tests.
	function createAutoTest( counter, source, expected )
	{
		var test = tests[ 'autoTest' + ( counter + 1000 ).toString().substr( 1 ) ] = function()
		{
			assertEquals( expected || source, CKPACKAGER.scriptCompressor.compress( source, true, null, true ) );
		};

		test.source = source;
		test.expected = expected || source;
	}

	for ( var i = 0 ; i < autoTests.length ; i++ )
	{
		var autoTest = autoTests[ i ];
		createAutoTest( i+1, autoTest[ 0 ], autoTest[ 1 ] );
	}

	// Run tests.
	var passCount = 0,
		failCount = 0;
	for ( var test in tests )
	{
		try
		{
			tests[ test ]();
			print( 'PASSED: (' + test + ') ' + tests[ test ].expected );
			passCount++;
		}
		catch ( error )
		{
			print( 'FAILED: (' + test + ')' );

			if ( !error.expected )
				throw error;

			print( '  Expected: ' + error.expected );
			print( '  Actual  : ' + error.actual );

			failCount++;
		}
	}

	print( '' );
	print( 'Finished: ' + passCount + ' passed / ' + failCount + ' failed' );
})();
