Property definitions

nitc $ TestSuite :: defaultinit
# A test suite contains all the test cases for a `MModule`.
class TestSuite

	# `MModule` under test
	var mmodule: MModule

	# `ToolContext` to use to display messages.
	var toolcontext: ToolContext

	# List of `TestCase` to be executed in this suite.
	var test_classes = new Array[TestClass]

	# Tests to be executed before the whole test suite.
	var before_all = new Array[TestCase]

	# Tests to be executed after the whole test suite.
	var after_all = new Array[TestCase]

	# Display test suite status in std-out.
	fun show_status do
		var test_cases = new Array[TestCase]
		for test_class in test_classes do
			test_cases.add_all test_class.before_all
			test_cases.add_all test_class.test_cases
			test_cases.add_all test_class.after_all
		end
		test_cases.add_all before_all
		test_cases.add_all after_all
		toolcontext.show_unit_status("Test-suite of module " + mmodule.full_name, test_cases)
	end

	# Execute the test suite
	fun run do
		set_env
		show_status
		if not toolcontext.test_dir.file_exists then
			toolcontext.test_dir.mkdir
		end
		write_to_nit
		compile
		if failure != null then
			for test_class in test_classes do
				for case in test_class.test_cases do
					case.fail "Compilation Error"
					case.raw_output = failure
					toolcontext.clear_progress_bar
					toolcontext.show_unit(case)
				end
			end
			show_status
			print ""
			return
		end
		toolcontext.info("Execute test-suite {mmodule.name}", 1)

		for before_module in before_all do
			before_module.run
			toolcontext.clear_progress_bar
			toolcontext.show_unit(before_module)
			if before_module.error != null then
				for test_class in test_classes do
					for case in test_class.before_all do
						case.fail "Nitunit Error: before module test failed"
						toolcontext.clear_progress_bar
						toolcontext.show_unit(case)
					end
					for case in test_class.test_cases do
						case.fail "Nitunit Error: before module test failed"
						toolcontext.clear_progress_bar
						toolcontext.show_unit(case)
					end
					for case in test_class.after_all do
						case.fail "Nitunit Error: before module test failed"
						toolcontext.clear_progress_bar
						toolcontext.show_unit(case)
					end
				end
				for after_module in after_all do
					after_module.fail "Nitunit Error: before module test failed"
					toolcontext.clear_progress_bar
					toolcontext.show_unit(after_module)
				end
				show_status
				print ""
				return
			end
		end

		for test_class in test_classes do
			for case in test_class.before_all do
				case.run
				toolcontext.clear_progress_bar
				toolcontext.show_unit(case)
				if case.error != null then
					for scase in test_class.test_cases do
						scase.fail "Nitunit Error: before class test failed"
						toolcontext.clear_progress_bar
						toolcontext.show_unit(scase)
					end
					for scase in test_class.after_all do
						scase.fail "Nitunit Error: before class test failed"
						toolcontext.clear_progress_bar
						toolcontext.show_unit(scase)
					end
					show_status
					print ""
					return
				end
			end
			for case in test_class.test_cases do
				case.run
				toolcontext.clear_progress_bar
				toolcontext.show_unit(case)
				show_status
			end
			for after_class in test_class.after_all do
				after_class.run
				toolcontext.clear_progress_bar
				toolcontext.show_unit(after_class)
				show_status
			end
		end

		for after_module in after_all do
			after_module.run
			toolcontext.clear_progress_bar
			toolcontext.show_unit(after_module)
			show_status
		end

		show_status
		print ""
	end

	# Write the test unit for `self` in a nit compilable file.
	fun write_to_nit do
		var file = new Template
		file.addn "intrude import core"
		file.addn "import {mmodule.name}\n"
		file.addn "var name = args.first"
		for before_module in before_all do
			before_module.write_to_nit(file)
		end
		for test_class in test_classes do
			for case in test_class.before_all do
				case.write_to_nit(file)
			end
			for case in test_class.test_cases do
				case.write_to_nit(file)
			end
			for case in test_class.after_all do
				case.write_to_nit(file)
			end
		end
		for after_module in after_all do
			after_module.write_to_nit(file)
		end
		file.write_to_file("{test_file}.nit")
	end

	# Return the test suite in XML format compatible with Jenkins.
	# Contents depends on the `run` execution.
	fun to_xml: HTMLTag do
		var n = new HTMLTag("testsuite")
		n.attr("package", mmodule.name)
		for test_class in test_classes do
			for test in test_class.test_cases do n.add test.to_xml
		end
		return n
	end

	# Generated test file name.
	fun test_file: String do
		return toolcontext.test_dir / "gen_{mmodule.name.escape_to_c}"
	end

	# Compile all `test_cases` cases in one file.
	fun compile do
		# find nitc
		var nitc = toolcontext.find_nitc
		# compile test suite
		var file = test_file
		var module_file = mmodule.location.file
		if module_file == null then
			toolcontext.error(null, "Error: cannot find module file for {mmodule.name}.")
			toolcontext.check_errors
			return
		end
		var include_dir = module_file.filename.dirname
		var cmd = "{nitc} --no-color -q '{file}.nit' -I {include_dir} -o '{file}.bin' > '{file}.out' 2>&1 </dev/null"
		var res = toolcontext.safe_exec(cmd)
		var f = new FileReader.open("{file}.out")
		var msg = f.read_all
		f.close
		if res != 0 then
			failure = msg
		end
	end

	# Set environment variables for test suite execution
	fun set_env do
		var loc = mmodule.location.file
		if loc == null then return
		toolcontext.set_testing_path(loc.filename)
	end

	# Error occured during test-suite compilation.
	var failure: nullable String = null
end
src/testing/testing_suite.nit:124,1--332,3