<?xml version="1.0" encoding="UTF-8"?>

<!--
   Copyright (c) 2009, 2024 Mountainminds GmbH & Co. KG and Contributors
   This program and the accompanying materials are made available under
   the terms of the Eclipse Public License 2.0 which is available at
   http://www.eclipse.org/legal/epl-2.0

   SPDX-License-Identifier: EPL-2.0

   Contributors:
      Brock Janiczak - initial API and implementation
      Dominik Stadler - source folder support
-->

<project name="JaCoCo Report Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">

	<target name="setUp">
		<tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
		<mkdir dir="${temp.dir}"/>
	</target>

	<target name="tearDown">
		<delete dir="${temp.dir}" quiet="false" failonerror="true" />
	</target>


	<target name="testReportNoStructureElement">
		<au:expectfailure expectedMessage="Group name must be supplied">
			<jacoco:report/>
		</au:expectfailure>
	</target>

	<target name="testReportNoStructureName">
		<au:expectfailure expectedMessage="Group name must be supplied">
			<jacoco:report>
				<structure/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportNoGroupName">
		<au:expectfailure expectedMessage="Group name must be supplied">
			<jacoco:report>
				<structure name="root">
					<group/>
				</structure>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportWithExecutiondataFiles">
		<jacoco:report>
			<executiondata>
				<fileset dir="${basedir}/data" includes="*.exec"/>
			</executiondata>
			<structure name="root"/>
		</jacoco:report>
	</target>

	<target name="testReportInvalidExecutionDataFile">
		<property name="doesnotexist.file" location="doesnotexist.exec"/>
		<au:expectfailure expectedMessage="Unable to read execution data file ${doesnotexist.file}">
			<jacoco:report>
				<executiondata>
					<file file="doesnotexist.exec"/>
				</executiondata>
				<structure name="root"/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportWithSourceButNoDebug">
		<java classname="org.jacoco.ant.RemoveDebugInfos" fork="true" classpath="${java.class.path}" failonerror="true">
			<arg value="${org.jacoco.ant.reportTaskTest.classes.dir}/org/jacoco/ant/TestTarget.class" />
			<arg value="${temp.dir}/TestTarget.class" />
		</java>
		<jacoco:report>
			<structure name="root">
				<classfiles>
					<fileset dir="${temp.dir}" id="*.class" />
				</classfiles>
				<sourcefiles encoding="UTF-8">
					<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
		</jacoco:report>
		<au:assertLogContains level="warn" text="To enable source code annotation class files for bundle 'root' have to be compiled with debug information"/>
	</target>

	<target name="testReportWithSourceDirButNoDebug">
		<java classname="org.jacoco.ant.RemoveDebugInfos" fork="true" classpath="${java.class.path}" failonerror="true">
			<arg value="${org.jacoco.ant.reportTaskTest.classes.dir}/org/jacoco/ant/TestTarget.class" />
			<arg value="${temp.dir}/TestTarget.class" />
		</java>
		<jacoco:report>
			<structure name="root">
				<classfiles>
					<fileset dir="${temp.dir}" id="*.class" />
				</classfiles>
				<sourcefiles encoding="UTF-8">
					<dirset file="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
		</jacoco:report>
		<au:assertLogContains level="warn" text="To enable source code annotation class files for bundle 'root' have to be compiled with debug information"/>
	</target>

	<target name="testReportWithSourceButNoClasses">
		<jacoco:report>
			<structure name="root">
				<sourcefiles encoding="UTF-8">
					<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
		</jacoco:report>
		<au:assertLogDoesntContain level="warn" text="source code annotation"/>
	</target>

	<target name="testReportWithNoMatch">
		<property name="nomatch.file" location="${basedir}/data/nomatch.exec"/>
		<jacoco:report>
			<executiondata>
				<file file="${nomatch.file}"/>
			</executiondata>
			<structure name="root">
				<classfiles>
					<path location="${org.jacoco.ant.reportTaskTest.classes.dir}"/>
				</classfiles>
			</structure>
		</jacoco:report>
		<au:assertLogContains level="warn" text="Classes in bundle 'root' do not match with execution data."/>
		<au:assertLogContains level="warn" text="For report generation the same class files must be used as at runtime."/>
		<au:assertLogContains level="warn" text="Execution data for class org/jacoco/ant/TestTarget does not match."/>
	</target>


	<!-- HTML Output -->

	<target name="testReportHtmlNoDestdirOrDestfile">
		<au:expectfailure expectedMessage="Destination directory or file must be supplied for html report">
			<jacoco:report>
				<structure name="root"/>
				<html/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportHtmlBothDestdirAndDestfile">
		<au:expectfailure expectedMessage="Either destination directory or file must be supplied, not both">
			<jacoco:report>
				<structure name="root"/>
				<html destdir="${temp.dir}" destfile="${temp.dir}/report.zip"/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportHtmlWithClassFileSet">
		<jacoco:report>
			<structure name="Test">
				<group name="Group">
					<classfiles>
						<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
					</classfiles>
				</group>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/>
	</target>

	<target name="testReportHtmlWithPath">
		<jacoco:report>
			<structure name="Test">
				<group name="Group">
					<classfiles>
						<path location="${org.jacoco.ant.reportTaskTest.classes.dir}"/>
					</classfiles>
				</group>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/>
	</target>

	<target name="testReportHtmlWithJAR">
		<property name="testReportHtmlWithJAR.jarfile" location="${temp.dir}/testclasses.jar"/>
		<jar destfile="${testReportHtmlWithJAR.jarfile}">
			<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
		</jar>
		<jacoco:report>
			<structure name="Test">
				<group name="Group">
					<classfiles>
						<file file="${testReportHtmlWithJAR.jarfile}"/>
					</classfiles>
				</group>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/>
	</target>

	<target name="testReportHtmlFooter">
		<jacoco:report>
			<structure name="Test"/>
			<html footer="ExampleFooter" destdir="${temp.dir}"/>
		</jacoco:report>

		<loadfile property="testReportHtmlFooter.content" srcfile="${temp.dir}/index.html" encoding="UTF-8"/>
		<au:assertTrue message="Footer not included in ${testReportHtmlFooter.content}">
			<contains string="${testReportHtmlFooter.content}" substring="ExampleFooter"/>
		</au:assertTrue>
	</target>

	<target name="testReportHtmlEncoding">
		<jacoco:report>
			<structure name="Test"/>
			<html encoding="UTF-16" destdir="${temp.dir}"/>
		</jacoco:report>

		<loadfile property="testReportHtmlEncoding.content" srcfile="${temp.dir}/index.html" encoding="UTF-16"/>
		<au:assertTrue message="Encoding not set in ${testReportHtmlEncoding.content}">
			<contains string="${testReportHtmlEncoding.content}" substring="encoding=&quot;UTF-16&quot;"/>
		</au:assertTrue>
	</target>

	<target name="testReportHtmlDefaultTabWidth">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
				<sourcefiles encoding="UTF-8">
					<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<loadfile property="testReportHtmlTabWidth.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
		<au:assertTrue message="Tab width not set in ${testReportHtmlTabWidth.content}">
			<contains string="${testReportHtmlTabWidth.content}" substring="window['PR_TAB_WIDTH']=4"/>
		</au:assertTrue>
	</target>

	<target name="testReportHtmlTabWidth">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
				<sourcefiles encoding="UTF-8" tabwidth="13">
					<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<loadfile property="testReportHtmlTabWidth.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
		<au:assertTrue message="Tab width not set in ${testReportHtmlTabWidth.content}">
			<contains string="${testReportHtmlTabWidth.content}" substring="window['PR_TAB_WIDTH']=13"/>
		</au:assertTrue>
	</target>

	<target name="testReportHtmlInvalidTabWidth">
		<au:expectfailure expectedMessage="Tab width must be greater than 0">
			<jacoco:report>
				<structure name="Test">
					<classfiles>
						<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
					</classfiles>
					<sourcefiles encoding="UTF-8" tabwidth="0">
						<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
					</sourcefiles>
				</structure>
				<html destdir="${temp.dir}"/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportHtmlZipFile">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
			</structure>
			<html destfile="${temp.dir}/report.zip"/>
		</jacoco:report>

		<au:assertFileExists file="${temp.dir}/report.zip"/>
	</target>

	<target name="testReportHtmlWithSources">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
				<sourcefiles encoding="UTF-8">
					<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<au:assertFileExists file="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
		<au:assertFileExists file="${temp.dir}/default/TestTargetInDefault.java.html"/>
	</target>

	<target name="testReportHtmlWithSourcesDir">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
				<sourcefiles encoding="UTF-8">
					<dirset dir="${org.jacoco.ant.reportTaskTest.sources.dir}/.." includes="src" />
				</sourcefiles>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<au:assertFileExists file="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
		<au:assertFileExists file="${temp.dir}/default/TestTargetInDefault.java.html"/>
	</target>

	<target name="testReportHtmlWithSourceEncoding">
		<mkdir dir="${temp.dir}/org/jacoco/ant"/>
		<echo file="${temp.dir}/org/jacoco/ant/TestTarget.java" encoding="UTF-16">Source Code</echo>
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
				<sourcefiles encoding="UTF-16">
					<fileset dir="${temp.dir}" />
				</sourcefiles>
			</structure>
			<html destdir="${temp.dir}"/>
		</jacoco:report>

		<loadfile property="testReportHtmlWithSourceEncoding.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html" encoding="UTF-8"/>
		<au:assertTrue message="Report does not contain expected text.">
			<contains string="${testReportHtmlWithSourceEncoding.content}" substring="Source Code"/>
		</au:assertTrue>
	</target>

	<target name="testReportHtmlLocale">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
				<sourcefiles encoding="UTF-8">
					<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
				</sourcefiles>
			</structure>
			<html destdir="${temp.dir}" locale="gr"/>
		</jacoco:report>

		<loadfile property="testReportHtmlLocale.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html" encoding="UTF-8"/>
		<au:assertTrue message="Report does not contain expected language tag.">
			<contains string="${testReportHtmlLocale.content}" substring="lang=&quot;gr&quot;"/>
		</au:assertTrue>
	</target>

	<!-- CSV Output -->

	<target name="testReportCsvNoDestfile">
		<au:expectfailure expectedMessage="Destination file must be supplied for csv report">
			<jacoco:report>
				<structure name="root"/>
				<csv/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportCsvEncoding">
		<property name="testReportCsvEncoding.destfile" location="${temp.dir}/report.csv"/>
		<jacoco:report>
			<structure name="Test"/>
			<csv encoding="UTF-16" destfile="${testReportCsvEncoding.destfile}"/>
		</jacoco:report>

		<au:assertFileExists file="${testReportCsvEncoding.destfile}"/>
		<loadfile property="testReportCsvEncoding.content" srcfile="${testReportCsvEncoding.destfile}" encoding="UTF-16"/>
		<au:assertTrue message="Encoding not set in ${testReportCsvEncoding.content}">
			<contains string="${testReportCsvEncoding.content}" substring="METHOD_COVERED"/>
		</au:assertTrue>
	</target>


	<!-- XML Output -->

	<target name="testReportXmlNoDestfile">
		<au:expectfailure expectedMessage="Destination file must be supplied for xml report">
			<jacoco:report>
				<structure name="root"/>
				<xml/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportXmlInvalidDestfile">
		<au:expectfailure expectedMessage="Error while creating report">
			<jacoco:report>
				<structure name="root"/>
				<xml destfile="${temp.dir}"/>
			</jacoco:report>
		</au:expectfailure>
	</target>

	<target name="testReportXmlEncoding">
		<property name="testReportXmlEncoding.destfile" location="${temp.dir}/report.xml"/>
		<jacoco:report>
			<structure name="Test"/>
			<xml encoding="UTF-16" destfile="${testReportXmlEncoding.destfile}"/>
		</jacoco:report>

		<au:assertFileExists file="${testReportXmlEncoding.destfile}"/>
		<loadfile property="testReportXmlEncoding.content" srcfile="${testReportXmlEncoding.destfile}" encoding="UTF-16"/>
		<au:assertTrue message="Encoding not set in ${testReportXmlEncoding.content}">
			<contains string="${testReportXmlEncoding.content}" substring="encoding=&quot;UTF-16&quot;"/>
		</au:assertTrue>
	</target>

	<!-- Coverage Check -->

	<target name="testReportCheckOk">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
			</structure>
			<check>
				<rule element="CLASS">
					<limit counter="METHOD" value="MISSEDCOUNT" maximum="100"/>
				</rule>
			</check>
		</jacoco:report>
	</target>

	<target name="testReportCheckFailed">
		<au:expectfailure expectedMessage="Coverage check failed due to violated rules.">
			<jacoco:report>
				<structure name="Test">
					<classfiles>
						<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
					</classfiles>
				</structure>
				<check>
					<rule element="BUNDLE">
						<limit counter="INSTRUCTION" value="COVEREDRATIO" minimum="0.90"/>
					</rule>
				</check>
			</jacoco:report>
		</au:expectfailure>
		<au:assertLogContains level="error" text="instructions covered ratio is 0.00, but expected minimum is 0.90"/>
	</target>

	<target name="testReportInvalidConfiguration">
		<au:expectfailure expectedMessage="Coverage check failed due to violated rules.">
			<jacoco:report>
				<structure name="Test">
					<classfiles>
						<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
					</classfiles>
				</structure>
				<check>
					<rule element="BUNDLE">
						<limit counter="INSTRUCTION" value="COVEREDRATIO" minimum="80"/>
					</rule>
				</check>
			</jacoco:report>
		</au:expectfailure>
		<au:assertLogContains level="error" text="given minimum ratio is 80, but must be between 0.0 and 1.0"/>
	</target>

	<target name="testReportCheckSetPropertyOnly">
		<jacoco:report>
			<structure name="Test">
				<classfiles>
					<fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
				</classfiles>
			</structure>
			<check failonviolation="false" violationsproperty="violation">
				<rule element="BUNDLE">
					<limit counter="METHOD" value="COVEREDRATIO" minimum="0.50"/>
					<limit counter="INSTRUCTION" value="COVEREDRATIO" minimum="0.90"/>
				</rule>
			</check>
		</jacoco:report>
		<au:assertLogContains level="error" text="methods covered ratio is 0.00, but expected minimum is 0.50"/>
		<au:assertLogContains level="error" text="instructions covered ratio is 0.00, but expected minimum is 0.90"/>
		<au:assertTrue message="Property is not set">
			<contains string="${violation}" substring="methods covered ratio is 0.00, but expected minimum is 0.50"/>
		</au:assertTrue>
		<au:assertTrue message="Property is not set">
			<contains string="${violation}" substring="instructions covered ratio is 0.00, but expected minimum is 0.90"/>
		</au:assertTrue>
	</target>


</project>
