/*
 * Copyright 2016 DiffPlug
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.diffplug.gradle.spotless;

import java.io.IOException;

import org.junit.Test;

public class UpToDateTest extends GradleIntegrationTest {
	/** Requires that README be lowercase. */
	private void writeBuildFile() throws IOException {
		setFile("build.gradle").toLines(
				"plugins {",
				"    id 'com.diffplug.gradle.spotless'",
				"}",
				"spotless {",
				"    format 'misc', {",
				"        target file('README.md')",
				"        customLazyGroovy('lowercase') {",
				"             return { str -> str.toLowerCase(Locale.ROOT) }",
				"        }",
				"        bumpThisNumberIfACustomStepChanges(1)",
				"    }",
				"}");
	}

	@Test
	public void testNormalCase() throws IOException {
		writeBuildFile();
		setFile("README.md").toContent("ABC");
		// first time, the task runs as expected
		applyIsUpToDate(false);
		assertFile("README.md").hasContent("abc");
		// because a file was changed (by spotless),
		// up-to-date is false, even though nothing is
		// going to change during this run.  This second
		// run is very fast though, because it will
		// only run on the few files that were changed.
		applyIsUpToDate(false);
		// it's not until the third run that everything
		// is totally up-to-date
		applyIsUpToDate(true);
	}

	@Test
	public void testNearPathologicalCase() throws IOException {
		writeBuildFile();
		setFile("README.md").toContent("ABC");
		// first time, up-to-date is false
		applyIsUpToDate(false);
		assertFile("README.md").hasContent("abc");

		// now we'll change the file
		setFile("README.md").toContent("AB");
		// as expected, the task will run again
		applyIsUpToDate(false);
		assertFile("README.md").hasContent("ab");
		// and it'll take two more runs to get to up-to-date
		applyIsUpToDate(false);
		applyIsUpToDate(true);
	}

	@Test
	public void testPathologicalCase() throws IOException {
		writeBuildFile();
		setFile("README.md").toContent("ABC");
		// first time, up-to-date is false
		applyIsUpToDate(false);
		assertFile("README.md").hasContent("abc");

		// now we'll change the file back to EXACTLY its original content
		setFile("README.md").toContent("ABC");
		// the task should run again, but instead the next line will
		// fail an assertion, because the task is actually reported as up-to-date
		applyIsUpToDate(false);
		assertFile("README.md").hasContent("abc");
		// and it'll take two more runs to get to up-to-date
		applyIsUpToDate(false);
		applyIsUpToDate(true);
	}
}

@@ -653,16 +653,148 @@
 ption;%0A%0A
+import org.assertj.core.api.Assertions;%0Aimport org.gradle.testkit.runner.BuildResult;%0Aimport org.gradle.testkit.runner.TaskOutcome;%0A
 import o
@@ -2644,37 +2644,55 @@
 rst time
-, up-to-date is false
+ running apply, no tasks are UP-TO-DATE
 %0A%09%09apply
@@ -2861,24 +2861,25 @@
 ent(%22ABC%22);%0A
+%0A
 %09%09// the tas
@@ -2879,161 +2879,418 @@
 the 
-task should run again, but instead the next line will%0A%09%09// fail an assertion, because the task is actually reported as up-to-date%0A%09%09applyIsUpToDate(false
+format task is UP-TO-DATE (same inputs), but the apply tasks will run again%0A%09%09pauseForFilesystem();%0A%09%09BuildResult buildResult = gradleRunner().withArguments(%22spotlessApply%22).build();%0A%09%09Assertions.assertThat(buildResult.taskPaths(TaskOutcome.UP_TO_DATE)).containsExactly(%22:spotlessMisc%22);%0A%09%09Assertions.assertThat(buildResult.taskPaths(TaskOutcome.SUCCESS)).containsExactly(%22:spotlessMiscApply%22, %22:spotlessApply%22
 );%0A%09
@@ -3329,24 +3329,25 @@
 ent(%22abc%22);%0A
+%0A
 %09%09// and it'
@@ -3374,34 +3374,40 @@
 s to get to 
-up-to-date
+fully UP-TO-DATE
 %0A%09%09applyIsUp

Update test for changed reporting in pathological case