<script src="../JavascriptTestRunner.js"></script>
<script src="../MultifileRunner.js"></script>
<script language="javascript">   

var runner = new TestRunner();   

// These 'prototype' assignments allow us to override the hard-wired dependencies
// and inject these fake dependencies so we can isolate the module under test.
//
MultifileRunner.prototype.dw 		= new FakeDreamweaver();
MultifileRunner.prototype.DWfile 	= new FakeDWfile();

function FakeDreamweaver()
{
	// For mocking.
	this.runJavascriptTestFileRunCallCount = 0;
	this.runJavascriptTestFileReturnValues = [];
	// End for mocking.
	
	this.getConfigurationPath = function() 
		{
			return 'file:///c/DWConfig';	
		}
		
	this.runJavascriptTestFile = function(fileUrl, strAction)
		{
			var curCount = this.runJavascriptTestFileRunCallCount++;
			return this.runJavascriptTestFileReturnValues[curCount];
		}
}

function FakeDWfile() // Used to test the collection of test file urls.
{
	// For mocking.
	this.listFilesCallCount = 0;
	this.listDirectoriesCallCount = 0;
	this.unrecognizedListFolderKindParam = false;
	var path = new FakeDreamweaver().getConfigurationPath();
	this.fileUrlList = 	[	path + '/JavascriptTests/TestFiles/TestFile1.htm', 
							path + '/JavascriptTests/TestFiles/TestFile2.htm',
							path + '/JavascriptTests/TestFiles/SubFolder/TestFile3.htm'
						];
	// End for mocking.
	
	this.listFolder = function(dir, kind)
		{
			if (kind == 'files')
			{
				this.listFilesCallCount++;
				if (this.listFilesCallCount == 1)
					return ['TestFile1.htm', 'TestFile2.htm'];	
				if (this.listFilesCallCount == 2)
					return ['TestFile3.htm'];	
				return [];
			}
			else if (kind == 'directories')
			{
				this.listDirectoriesCallCount++;
				if (this.listDirectoriesCallCount == 1)
					return ['SubFolder'];
				return [];
			}
			else
				this.unrecognizedListFolderKindParam = true;
		}
}

runner.addTestCase( 
{	
	name: 	'Should be able to create a MultifileRunner.',
	
	given: 	'',
	when: 	'',
	
	test: 	function() 
			{
				var multifileRunner = new MultifileRunner();
				
				runner.assertEqual('multifileRunner should be a Javascript object.', 		typeof multifileRunner, 		'object' ); 
				runner.assertEqual('multifileRunner.dw should be a Javascript object.', 	typeof multifileRunner.dw, 		'object' ); 
				runner.assertEqual('multifileRunner.DWfile should be a Javascript object.', typeof multifileRunner.DWfile, 	'object' ); 
			} 
});

runner.addTestCase( 
{	
	name: 	'multifileRunner.getTestFileUrlList() should return an array of file ' + 
				'urls of all the test files in the "JavascriptTests/TestFiles" directory tree.',
	
	given: 	'',
	when: 	'',

	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				var fileUrlList = [];
				multifileRunner.getTestFileUrlList(multifileRunner.dw.getConfigurationPath() + '/JavascriptTests/TestFiles', fileUrlList);
				
				runner.assertFalse("No unrecognized 'kind' params should be passed in.", multifileRunner.DWfile.unrecognizedListFolderKindParam);
				runner.assertArraysEqual("fileUrlList array should be same as FakeDWfile's fileUrlList.", 	fileUrlList, multifileRunner.DWfile.fileUrlList);
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle one test file with 33 passing test cases.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				multifileRunner.getTestFileUrlList = function(dir, list) { list.push(''); } // Just need the correct file count of one.
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues = [{status:'passed', numTestCases:33}];
				var results = multifileRunner.runTests();
				
				runner.assertEqual('Status should be passed.', 		results.status, 		'passed'	);
				runner.assertEqual('numTestFiles should be 1.', 	results.numTestFiles, 	1			);
				runner.assertEqual('numTestCases should be 33.', 	results.numTestCases, 	33			);
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle one test file with 2 failing test cases.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				
				multifileRunner.getTestFileUrlList = function(dir, list) { list.push('file:///c/DreamweaverConfigurationPath/TestFile1.htm'); } 
				
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues =	
				
					[	{	status:		'failed', 
							records:	[	{testFileUrl:'file:///c/DreamweaverConfigurationPath/TestFile1.htm', testCase:'First test case', 	message:'Message1'},
											{testFileUrl:'file:///c/DreamweaverConfigurationPath/TestFile1.htm', testCase:'Second test case', 	message:'Message2'}
										]
						}
					]; 

				var results = multifileRunner.runTests();
				
				runner.assertEqual('results.status should be failed.', 		results.status, 		'failed'	);
				runner.assertEqual('status.records.length should be 2.', 	results.records.length, 2			);
				
				runner.assertEqual('status.records[0].testFileUrl should be correct.', 
																results.records[0].testFileUrl, 
																'file:///c/DreamweaverConfigurationPath/TestFile1.htm');
																
				runner.assertEqual('status.records[1].message should be correct.', results.records[1].message, 'Message2');				
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle one test file with 2 passing test cases and one test file with one failing test case.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				
				multifileRunner.getTestFileUrlList = function(dir, list){ list.push(''); list.push('file:///c/DreamweaverConfigurationPath/TestFile2.htm'); } 
				
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues =	
				
					[	
						{	status:		'passed', 	numTestCases: 2		},					
					
						{	status:		'failed', 
							records:	[{testFileUrl:'file:///c/DreamweaverConfigurationPath/TestFile2.htm', testCase:'First test case', message:'Message1'}]
						}
					]; 

				var results = multifileRunner.runTests();
				
				runner.assertEqual('results.status should be failed.', 		results.status, 		'failed'	);
				runner.assertEqual('status.records.length should be 1.', 	results.records.length, 1			);
				
				runner.assertEqual('status.records[0].testFileUrl should be correct.', 
																results.records[0].testFileUrl, 
																'file:///c/DreamweaverConfigurationPath/TestFile2.htm');
																
				runner.assertEqual('status.records[0].testCase should be correct.', results.records[0].testCase, 'First test case');				
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle two test files with 2 and 3 passing tests respectively.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				
				multifileRunner.getTestFileUrlList = function(dir, list) { list.push(''); list.push(''); } // Just need the correct file count of two.
				
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues =	
				
					[	
						{	status:		'passed', 	numTestCases: 2		},					
						{	status:		'passed', 	numTestCases: 3		}									
					]; 

				var results = multifileRunner.runTests();
				
				runner.assertEqual('results.status should be passed.', 	results.status, 		'passed'	);
				runner.assertEqual('results.numTestFiles should be 2.', results.numTestFiles, 	2			);
				runner.assertEqual('results.numTestCases should be 5.', results.numTestCases, 	5			);				
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle when an error occurs and not all of the test files can be run.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				
				var testFileUrl = 'file:///c/DreamweaverConfigurationPath/TestFile1.htm';
				multifileRunner.getTestFileUrlList = function(dir, list) { list.push(testFileUrl); } // Just need the correct file count of one.
				
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues =	
				
					[	
						{	status:			'error', 
							dwMessage: 		'Unable to run tests--could not compile.', 
							jsMessage: 		'Msg from interpreter.'
						}
					]; 
																		
				var results = multifileRunner.runTests();
				
				runner.assertEqual('results.status should be error.', results.status, 'error');	
				
				var rec = multifileRunner.dw.runJavascriptTestFileReturnValues[0];
				runner.assertEqual('results.testFileUrl should be same as what getTestFileUrlList() returns.', 			results.testFileUrl, 	testFileUrl);
				runner.assertEqual('results.dwMessage should be same as what dw.runJavascriptTestFile() returns.', 		results.dwMessage, 		rec.dwMessage);
				runner.assertEqual('results.jsMessage should be same as what dw.runJavascriptTestFile() returns.', 		results.jsMessage, 		rec.jsMessage);
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle when there are no test files.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				
				multifileRunner.getTestFileUrlList = function(dir, list) {} // Just need the correct file count of zero.
				
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues = []; 
																		
				var results = multifileRunner.runTests();
				
				runner.assertEqual('results.status should be passed.', 	results.status, 		'passed'	);
				runner.assertEqual('numTestFiles should be 0.', 		results.numTestFiles, 	0			);
				runner.assertEqual('numTestCases should be 0.', 		results.numTestCases, 	0			);
			}
});

runner.addTestCase( 
{
	name:	'runTests() should handle when there is one test file that has zero test cases.',
	test: 	function()
			{
				var multifileRunner = new MultifileRunner();
				
				multifileRunner.getTestFileUrlList = function(dir, list) { list.push(''); } // Just need the correct file count.
				
				multifileRunner.dw.runJavascriptTestFileRunCallCount = 0;
				multifileRunner.dw.runJavascriptTestFileReturnValues = [{status:'passed', numTestFiles:1, numTestCases:0}]; 
				var results = multifileRunner.runTests();
				
				runner.assertEqual('results.status should be passed.', 	results.status, 		'passed'	);
				runner.assertEqual('numTestFiles should be 1.', 		results.numTestFiles, 	1			);
				runner.assertEqual('numTestCases should be 0.', 		results.numTestCases, 	0			);
			}
});
