Refactor and improve tests (#466)
* Install and run a production server in tests * Small improvements * Add FabricAPI build test Create new GradleProjectTestTrait replacing the old trait Improve groovy code formatting. * Refactor tests * Fix MultiProjectTest + fix logging for fabric api test * Cleanup and fixes * Update fabric api + run in parallel for speed * Set server memory + fix error
This commit is contained in:
		
							parent
							
								
									2277b93f8d
								
							
						
					
					
						commit
						3ded0964c4
					
				
					 34 changed files with 807 additions and 481 deletions
				
			
		|  | @ -104,6 +104,7 @@ dependencies { | |||
| 		exclude module: 'groovy-all' | ||||
| 	} | ||||
| 	testImplementation 'io.javalin:javalin:3.13.9' | ||||
| 	testImplementation 'net.fabricmc:fabric-installer:0.7.4' | ||||
| 
 | ||||
| 	compileOnly 'org.jetbrains:annotations:21.0.1' | ||||
| } | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ ruleset { | |||
|     SpaceAfterSwitch | ||||
|     SpaceAfterWhile | ||||
|     SpaceAroundClosureArrow | ||||
|     SpaceAroundMapEntryColon | ||||
|     SpaceAroundMapEntryColon(characterAfterColonRegex: /\ /) | ||||
|     SpaceAroundOperator | ||||
|     SpaceBeforeClosingBrace | ||||
|     SpaceBeforeOpeningBrace | ||||
|  | @ -61,6 +61,13 @@ ruleset { | |||
|     FieldTypeRequired | ||||
|     MethodParameterTypeRequired | ||||
| 
 | ||||
|     // Imports | ||||
|     UnusedImport | ||||
|     UnnecessaryGroovyImport | ||||
|     NoWildcardImports(ignoreStaticImports: true) | ||||
|     ImportFromSamePackage | ||||
|     DuplicateImport | ||||
| 
 | ||||
|     //Misc | ||||
|     LongLiteralWithLowerCaseL | ||||
| } | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ import java.io.IOException; | |||
| import java.io.InputStreamReader; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.Objects; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
|  | @ -36,6 +37,7 @@ import java.util.stream.StreamSupport; | |||
| import java.util.zip.ZipEntry; | ||||
| import java.util.zip.ZipFile; | ||||
| 
 | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonPrimitive; | ||||
| import org.gradle.api.Project; | ||||
|  | @ -108,7 +110,13 @@ public final class MixinRefmapHelper { | |||
| 
 | ||||
| 	@NotNull | ||||
| 	private static Collection<String> getMixinConfigurationFiles(JsonObject fabricModJson) { | ||||
| 		return StreamSupport.stream(fabricModJson.getAsJsonArray("mixins").spliterator(), false) | ||||
| 		JsonArray mixins = fabricModJson.getAsJsonArray("mixins"); | ||||
| 
 | ||||
| 		if (mixins == null) { | ||||
| 			return Collections.emptyList(); | ||||
| 		} | ||||
| 
 | ||||
| 		return StreamSupport.stream(mixins.spliterator(), false) | ||||
| 				.map(e -> { | ||||
| 					if (e instanceof JsonPrimitive str) { | ||||
| 						return str.getAsString(); | ||||
|  |  | |||
|  | @ -54,7 +54,7 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { | |||
| 	protected void addDependencies(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) { | ||||
| 		if (jarProcessorManager.isInvalid(projectMappedJar) || isRefreshDeps()) { | ||||
| 			getProject().getLogger().info(":processing mapped jar"); | ||||
| 			invalidateJars(); | ||||
| 			invalidateJar(); | ||||
| 
 | ||||
| 			try { | ||||
| 				FileUtils.copyFile(super.getMappedJar(), projectMappedJar); | ||||
|  | @ -69,16 +69,14 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { | |||
| 				getProject().getDependencies().module("net.minecraft:minecraft-" + projectMappedClassifier + ":" + getMinecraftProvider().minecraftVersion() + "/" + getExtension().getMappingsProvider().mappingsIdentifier())); | ||||
| 	} | ||||
| 
 | ||||
| 	private void invalidateJars() { | ||||
| 		File dir = projectMappedJar.getParentFile(); | ||||
| 
 | ||||
| 		if (dir.exists()) { | ||||
| 			getProject().getLogger().warn("Invalidating project jars"); | ||||
| 	private void invalidateJar() { | ||||
| 		if (projectMappedJar.exists()) { | ||||
| 			getProject().getLogger().warn("Invalidating project jar"); | ||||
| 
 | ||||
| 			try { | ||||
| 				FileUtils.cleanDirectory(dir); | ||||
| 				FileUtils.forceDelete(projectMappedJar); | ||||
| 			} catch (IOException e) { | ||||
| 				throw new RuntimeException("Failed to invalidate jars, try stopping gradle daemon or closing the game", e); | ||||
| 				throw new RuntimeException("Failed to invalidate jar, try stopping gradle daemon or closing the game", e); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016-2021 FabricMC | ||||
|  * Copyright (c) 2021 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  | @ -22,25 +22,11 @@ | |||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.test.util | ||||
| package net.fabricmc.loom.test | ||||
| 
 | ||||
| import org.zeroturnaround.zip.ZipUtil | ||||
| class LoomTestConstants { | ||||
|     public final static String DEFAULT_GRADLE = "7.0.1" | ||||
|     public final static String PRE_RELEASE_GRADLE = "7.3-20210827230026+0000" | ||||
| 
 | ||||
| trait ArchiveAssertionsTrait { | ||||
| 	String getArchiveEntry(String name, String entry, String project = "") { | ||||
| 		def file = getOutputFile(name, project) | ||||
| 
 | ||||
| 		def bytes = ZipUtil.unpackEntry(file, entry) | ||||
| 
 | ||||
| 		if (bytes == null) { | ||||
| 			throw new FileNotFoundException("Could not find ${entry} in ${name}") | ||||
| 		} | ||||
| 
 | ||||
| 		new String(bytes as byte[]) | ||||
| 	} | ||||
| 
 | ||||
| 	boolean hasArchiveEntry(String name, String entry, String project = "") { | ||||
| 		def file = getOutputFile(name, project) | ||||
| 		ZipUtil.unpackEntry(file, entry) != null | ||||
| 	} | ||||
|     public final static String[] STANDARD_TEST_VERSIONS = [DEFAULT_GRADLE, PRE_RELEASE_GRADLE] | ||||
| } | ||||
|  | @ -24,30 +24,25 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ArchiveAssertionsTrait | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class AccessWidenerTest extends Specification implements ProjectTestTrait, ArchiveAssertionsTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"accesswidener" | ||||
| 	} | ||||
| 
 | ||||
| class AccessWidenerTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "accesswidener (gradle #gradle)"() { | ||||
| 	def "accesswidener (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "accesswidener", version: version) | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 			getArchiveEntry("fabric-example-mod-1.0.0.jar", "modid.accesswidener") == expected().replaceAll('\r', '') | ||||
| 			gradle.getOutputZipEntry("fabric-example-mod-1.0.0.jar", "modid.accesswidener") == expected().replaceAll('\r', '') | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| 
 | ||||
| 	String expected() { | ||||
|  |  | |||
|  | @ -24,42 +24,36 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class CustomManifestTest extends Specification implements ProjectTestTrait { | ||||
|     @Override | ||||
|     String name() { | ||||
|         "minimalBase" | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     def filesReady() { | ||||
|         buildGradle() << ''' | ||||
|             loom { | ||||
|                 customMinecraftManifest = "https://maven.fabricmc.net/net/minecraft/1_18_experimental-snapshot-1.json" | ||||
|             } | ||||
| 
 | ||||
|             dependencies { | ||||
|                 minecraft "com.mojang:minecraft:1.18_experimental-snapshot-1" | ||||
|                 mappings "net.fabricmc:yarn:1.18_experimental-snapshot-1+build.2:v2" | ||||
|                 modImplementation "net.fabricmc:fabric-loader:0.11.6" | ||||
|             } | ||||
|         ''' | ||||
|     } | ||||
| 
 | ||||
| class CustomManifestTest extends Specification implements GradleProjectTestTrait { | ||||
|     @Unroll | ||||
|     def "customManifest (gradle #gradle)"() { | ||||
|     def "customManifest (gradle #version)"() { | ||||
|         setup: | ||||
|             def gradle = gradleProject(project: "minimalBase", version: version) | ||||
|             gradle.buildGradle << ''' | ||||
|                 loom { | ||||
|                     customMinecraftManifest = "https://maven.fabricmc.net/net/minecraft/1_18_experimental-snapshot-1.json" | ||||
|                 } | ||||
| 
 | ||||
|                 dependencies { | ||||
|                     minecraft "com.mojang:minecraft:1.18_experimental-snapshot-1" | ||||
|                     mappings "net.fabricmc:yarn:1.18_experimental-snapshot-1+build.2:v2" | ||||
|                     modImplementation "net.fabricmc:fabric-loader:0.11.6" | ||||
|                 } | ||||
|             ''' | ||||
|         when: | ||||
|             def result = create("build", gradle) | ||||
|             def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|             result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
|         where: | ||||
|             gradle              | _ | ||||
|             DEFAULT_GRADLE      | _ | ||||
|             PRE_RELEASE_GRADLE  | _ | ||||
|             version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,28 +24,27 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class DecompileTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"decompile" | ||||
| 	} | ||||
| 
 | ||||
| class DecompileTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "#decompiler gradle #gradle"() { | ||||
| 	def "#decompiler gradle #version"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "decompile", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create(task, gradle) | ||||
| 			def result = gradle.run(task: task) | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":${task}").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			decompiler 		| task								| gradle | ||||
| 			decompiler 		| task								| version | ||||
| 			'fernflower'	| "genSources"						| DEFAULT_GRADLE | ||||
| 			'fernflower'	| "genSources"						| PRE_RELEASE_GRADLE | ||||
| 			'cfr' 			| "genSourcesWithExperimentalCfr"	| DEFAULT_GRADLE | ||||
|  |  | |||
|  | @ -24,29 +24,27 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class DependencyResolutionManagementTest extends Specification implements ProjectTestTrait { | ||||
|     @Override | ||||
|     String name() { | ||||
|         "dependencyResolutionManagement" | ||||
|     } | ||||
| 
 | ||||
| class DependencyResolutionManagementTest extends Specification implements GradleProjectTestTrait { | ||||
|     @Unroll | ||||
|     def "build (gradle #gradle)"() { | ||||
|     def "build (gradle #version)"() { | ||||
|         setup: | ||||
|             def gradle = gradleProject(project: "dependencyResolutionManagement", version: version) | ||||
| 
 | ||||
|         when: | ||||
|             def result = create("build", gradle) | ||||
|             def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|             result.task(":basic:build").outcome == SUCCESS | ||||
|             result.task(":projmap:build").outcome == SUCCESS | ||||
| 
 | ||||
|         where: | ||||
|         gradle              | _ | ||||
|         DEFAULT_GRADLE      | _ | ||||
|         PRE_RELEASE_GRADLE  | _ | ||||
|             version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,38 +24,34 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class ExperimentalVersionsTest extends Specification implements ProjectTestTrait { | ||||
|     @Override | ||||
|     String name() { | ||||
|         "minimalBase" | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     def filesReady() { | ||||
|         buildGradle() << ''' | ||||
|             dependencies { | ||||
|                 minecraft "com.mojang:minecraft:1.18_experimental-snapshot-1" | ||||
|                 mappings "net.fabricmc:yarn:1.18_experimental-snapshot-1+build.2:v2" | ||||
|                 modImplementation "net.fabricmc:fabric-loader:0.11.6" | ||||
|             } | ||||
|         ''' | ||||
|     } | ||||
| 
 | ||||
| class ExperimentalVersionsTest extends Specification implements GradleProjectTestTrait { | ||||
|     @Unroll | ||||
|     def "experimental versions (gradle #gradle)"() { | ||||
|     def "experimental versions (gradle #version)"() { | ||||
|         setup: | ||||
|             def gradle = gradleProject(project: "minimalBase", version: version) | ||||
| 
 | ||||
|             gradle.buildGradle << ''' | ||||
|                 dependencies { | ||||
|                     minecraft "com.mojang:minecraft:1.18_experimental-snapshot-1" | ||||
|                     mappings "net.fabricmc:yarn:1.18_experimental-snapshot-1+build.2:v2" | ||||
|                     modImplementation "net.fabricmc:fabric-loader:0.11.6" | ||||
|                 } | ||||
|             ''' | ||||
| 
 | ||||
|         when: | ||||
|             def result = create("build", gradle) | ||||
|             def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|             result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
|         where: | ||||
|             gradle              | _ | ||||
|             DEFAULT_GRADLE      | _ | ||||
|             PRE_RELEASE_GRADLE  | _ | ||||
|             version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,69 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2021 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.ServerRunner | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Timeout | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import java.util.concurrent.TimeUnit | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| @Timeout(value = 30, unit = TimeUnit.MINUTES) | ||||
| class FabricAPITest extends Specification implements GradleProjectTestTrait { | ||||
| 	private static final String API_VERSION = "0.0.0+loom" | ||||
| 
 | ||||
| 	@Unroll | ||||
| 	def "build and run (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject( | ||||
| 					repo: "https://github.com/modmuss50/fabric.git", | ||||
| 					commit: "cb31cccd34cb91f70cae6bac80208f5ec3650f33", | ||||
| 					version: version | ||||
| 			) | ||||
| 
 | ||||
| 			// Set the version to something constant | ||||
| 			gradle.buildGradle.text = gradle.buildGradle.text.replace('Globals.baseVersion + "+" + (ENV.GITHUB_RUN_NUMBER ? "" : "local-") + getBranch()', "\"$API_VERSION\"") | ||||
| 
 | ||||
| 			def server = ServerRunner.create(gradle.projectDir, "1.17.1") | ||||
| 										.withMod(gradle.getOutputFile("fabric-api-${API_VERSION}.jar")) | ||||
| 		when: | ||||
| 			def result = gradle.run(tasks: ["build", "publishToMavenLocal"], args: ["--parallel", "-x", "check"]) // Note: checkstyle does not appear to like being ran in a test runner | ||||
| 			gradle.printOutputFiles() | ||||
| 
 | ||||
| 			def serverResult = server.run() | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 			serverResult.successful() | ||||
| 			serverResult.output.contains("fabric@$API_VERSION") | ||||
| 		where: | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  | @ -24,27 +24,26 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class Java16ProjectTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"java16" | ||||
| 	} | ||||
| 
 | ||||
| class Java16ProjectTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "build (gradle #gradle)"() { | ||||
| 	def "build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "java16", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,28 +24,26 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import spock.lang.IgnoreIf | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class KotlinTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"kotlin" | ||||
| 	} | ||||
| 
 | ||||
| class KotlinTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "kotlin build (gradle #gradle)"() { | ||||
| 	def "kotlin build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "kotlin", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,24 +24,27 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| // This test uses gradle 4.9 and 1.14.4 v1 mappings | ||||
| class LegacyProjectTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"legacy" | ||||
| 	} | ||||
| 
 | ||||
| class LegacyProjectTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "build"() { | ||||
| 	def "legacy build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "legacy", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", DEFAULT_GRADLE) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,27 +24,26 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class LocalFileDependencyTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"localFileDependency" | ||||
| 	} | ||||
| 
 | ||||
| class LocalFileDependencyTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "build (gradle #gradle)"() { | ||||
| 	def "build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "localFileDependency", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,13 +24,14 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ArchiveAssertionsTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.MockMavenServerTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Stepwise | ||||
| import spock.lang.Unroll | ||||
| import spock.util.environment.RestoreSystemProperties | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static java.lang.System.setProperty | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
|  | @ -38,20 +39,23 @@ import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | |||
|  * This tests publishing a range of versions and then tries to resolve and build against them | ||||
|  */ | ||||
| @Stepwise | ||||
| class MavenProjectTest extends Specification implements MockMavenServerTrait, ArchiveAssertionsTrait { | ||||
| class MavenProjectTest extends Specification implements MockMavenServerTrait, GradleProjectTestTrait { | ||||
| 	@RestoreSystemProperties | ||||
| 	@Unroll | ||||
| 	def "publish lib #version #gradle"() { | ||||
| 		given: | ||||
| 	def "publish lib #version #gradleVersion"() { | ||||
| 		setup: | ||||
| 			setProperty('loom.test.version', version) | ||||
| 			library = true | ||||
| 			def gradle = gradleProject(project: "mavenLibrary", version: gradleVersion, sharedFiles: true) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("publish", gradle) | ||||
| 			def result = gradle.run(tasks: ["clean", "publish"]) | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":publish").outcome == SUCCESS | ||||
| 			hasArchiveEntry("fabric-example-lib-${version}.jar", "net/fabricmc/example/ExampleLib.class") | ||||
| 			gradle.hasOutputZipEntry("fabric-example-lib-${version}.jar", "net/fabricmc/example/ExampleLib.class") | ||||
| 
 | ||||
| 		where: | ||||
| 			version           | gradle | ||||
| 			version           | gradleVersion | ||||
| 			'1.0.0'           | DEFAULT_GRADLE | ||||
| 			'1.0.0'           | PRE_RELEASE_GRADLE | ||||
| 			'1.1.0'           | DEFAULT_GRADLE | ||||
|  | @ -64,17 +68,20 @@ class MavenProjectTest extends Specification implements MockMavenServerTrait, Ar | |||
| 
 | ||||
| 	@RestoreSystemProperties | ||||
| 	@Unroll | ||||
| 	def "resolve #version #gradle"() { | ||||
| 	def "resolve #version #gradleVersion"() { | ||||
| 		given: | ||||
| 			setProperty('loom.test.resolve', "com.example:fabric-example-lib:${version}") | ||||
| 			library = false | ||||
| 			def gradle = gradleProject(project: "maven", version: gradleVersion, sharedFiles: true) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(tasks: ["clean", "build"]) | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 			hasArchiveEntry("fabric-example-mod-1.0.0.jar", "net/fabricmc/examplemod/ExampleMod.class") | ||||
| 			gradle.hasOutputZipEntry("fabric-example-mod-1.0.0.jar", "net/fabricmc/examplemod/ExampleMod.class") | ||||
| 
 | ||||
| 		where: | ||||
| 			version                      | gradle | ||||
| 			version                      | gradleVersion | ||||
| 			'1.0.0'                      | DEFAULT_GRADLE | ||||
| 			'1.0.0'                      | PRE_RELEASE_GRADLE | ||||
| 			'1.1.+'                      | DEFAULT_GRADLE | ||||
|  | @ -87,12 +94,4 @@ class MavenProjectTest extends Specification implements MockMavenServerTrait, Ar | |||
| 			'2.0.0-SNAPSHOT:classifier'  | DEFAULT_GRADLE | ||||
| 			'master-SNAPSHOT:classifier' | DEFAULT_GRADLE | ||||
| 	} | ||||
| 
 | ||||
| 	// Set to true when to build and publish the mavenLibrary | ||||
| 	private boolean library = false | ||||
| 
 | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		library ? "mavenLibrary" : "maven" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,53 +24,50 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| import com.google.gson.JsonParser; | ||||
| import java.util.jar.JarFile | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class MixinApAutoRefmapTest extends Specification implements ProjectTestTrait { | ||||
|     @Override | ||||
|     String name() { | ||||
|         "mixinApAutoRefmap" | ||||
|     } | ||||
| 
 | ||||
| class MixinApAutoRefmapTest extends Specification implements GradleProjectTestTrait { | ||||
|     @Unroll | ||||
|     def "build (gradle #gradle)"() { | ||||
|     def "build (gradle #version)"() { | ||||
|         setup: | ||||
|             def gradle = gradleProject(project: "mixinApAutoRefmap", version: version) | ||||
| 
 | ||||
|         when: | ||||
|         def result = create("build", gradle) | ||||
|             def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|         result.task(":build").outcome == SUCCESS | ||||
|             result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
|         // verify the ref-map name is correctly generated | ||||
|         def jar = new JarFile(getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile) | ||||
|         jar.getEntry("refmap0000.json") == null | ||||
|         jar.getEntry("refmap0001.json") != null | ||||
|         jar.getEntry("refmap0002.json") != null | ||||
|         jar.getEntry("refmap0003.json") != null | ||||
|             // verify the ref-map name is correctly generated | ||||
|             def jar = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile) | ||||
|             jar.getEntry("refmap0000.json") == null | ||||
|             jar.getEntry("refmap0001.json") != null | ||||
|             jar.getEntry("refmap0002.json") != null | ||||
|             jar.getEntry("refmap0003.json") != null | ||||
| 
 | ||||
|         def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json")))) | ||||
|         j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json" | ||||
|             def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json")))) | ||||
|             j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json" | ||||
| 
 | ||||
|         def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json")))) | ||||
|         j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json" | ||||
|             def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json")))) | ||||
|             j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json" | ||||
| 
 | ||||
|         def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json")))) | ||||
|         j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json" | ||||
|             def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json")))) | ||||
|             j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json" | ||||
| 
 | ||||
|         def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json")))) | ||||
|         !j4.asJsonObject.has("refmap") | ||||
|             def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json")))) | ||||
|             !j4.asJsonObject.has("refmap") | ||||
| 
 | ||||
|         def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json")))) | ||||
|         !j5.asJsonObject.has("refmap") | ||||
|             def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json")))) | ||||
|             !j5.asJsonObject.has("refmap") | ||||
| 
 | ||||
|         where: | ||||
|         gradle              | _ | ||||
|         DEFAULT_GRADLE      | _ | ||||
|         PRE_RELEASE_GRADLE  | _ | ||||
|             version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,40 +24,38 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| 
 | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import java.util.jar.JarFile | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class MixinApSimpleTest extends Specification implements ProjectTestTrait { | ||||
|     @Override | ||||
|     String name() { | ||||
|         "mixinApSimple" | ||||
|     } | ||||
| 
 | ||||
| class MixinApSimpleTest extends Specification implements GradleProjectTestTrait { | ||||
|     @Unroll | ||||
|     def "build (gradle #gradle)"() { | ||||
|     def "build (gradle #version)"() { | ||||
|         setup: | ||||
|             def gradle = gradleProject(project: "mixinApSimple", version: version) | ||||
| 
 | ||||
|         when: | ||||
|         def result = create("build", gradle) | ||||
|             def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|         result.task(":build").outcome == SUCCESS | ||||
|             result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
|         // verify the ref-map name is correctly generated | ||||
|         def main = new JarFile(getOutputFile("fabric-example-mod-1.0.0-dev.jar").absoluteFile) | ||||
|         main.getEntry("main-refmap0000.json") != null | ||||
|         def mixin = new JarFile(getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile) | ||||
|         mixin.getEntry("default-refmap0000.json") != null | ||||
|         def mixin1 = new JarFile(getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile) | ||||
|         mixin1.getEntry("main-refmap0000.json") == null | ||||
|         mixin1.getEntry("default-refmap0000.json") == null | ||||
|             // verify the ref-map name is correctly generated | ||||
|             def main = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-dev.jar").absoluteFile) | ||||
|             main.getEntry("main-refmap0000.json") != null | ||||
|             def mixin = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile) | ||||
|             mixin.getEntry("default-refmap0000.json") != null | ||||
|             def mixin1 = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile) | ||||
|             mixin1.getEntry("main-refmap0000.json") == null | ||||
|             mixin1.getEntry("default-refmap0000.json") == null | ||||
| 
 | ||||
|         where: | ||||
|         gradle              | _ | ||||
|         DEFAULT_GRADLE      | _ | ||||
|         PRE_RELEASE_GRADLE  | _ | ||||
|             version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,27 +24,26 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class MojangMappingsProjectTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"mojangMappings" | ||||
| 	} | ||||
| 
 | ||||
| class MojangMappingsProjectTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "build (gradle #gradle)"() { | ||||
| 	def "build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "mojangMappings", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,23 +24,22 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ArchiveAssertionsTrait | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class MultiProjectTest extends Specification implements ProjectTestTrait, ArchiveAssertionsTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"multiproject" | ||||
| 	} | ||||
| 
 | ||||
| class MultiProjectTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "build (gradle #gradle)"() { | ||||
| 	def "build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "multiproject", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 			result.task(":core:build").outcome == SUCCESS | ||||
|  | @ -49,13 +48,11 @@ class MultiProjectTest extends Specification implements ProjectTestTrait, Archiv | |||
| 			result.task(":remapAllJars").outcome == SUCCESS | ||||
| 			result.task(":remapAllSources").outcome == SUCCESS | ||||
| 
 | ||||
| 			hasArchiveEntry("multiproject-1.0.0.jar", "META-INF/jars/example-1.0.0.jar") | ||||
| 			hasArchiveEntry("multiproject-1.0.0.jar", "META-INF/jars/core-1.0.0.jar") | ||||
| 			hasArchiveEntry("multiproject-1.0.0.jar", "META-INF/jars/fabric-api-base-0.2.1+9354966b7d.jar") | ||||
| 			gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/example-1.0.0.jar") | ||||
| 			gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/core-1.0.0.jar") | ||||
| 			gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/fabric-api-base-0.2.1+9354966b7d.jar") | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -24,29 +24,26 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class ParchmentTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"parchment" | ||||
| 	} | ||||
| 
 | ||||
| class ParchmentTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "parchment #gradle"() { | ||||
| 	def "parchment #version"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "parchment", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -27,40 +27,37 @@ package net.fabricmc.loom.test.integration | |||
| import com.google.common.hash.HashCode | ||||
| import com.google.common.hash.Hashing | ||||
| import com.google.common.io.Files | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| import spock.util.environment.RestoreSystemProperties | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static java.lang.System.setProperty | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class ReproducibleBuildTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"reproducible" | ||||
| 	} | ||||
| 
 | ||||
| class ReproducibleBuildTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@RestoreSystemProperties | ||||
| 	@Unroll | ||||
| 	def "build (gradle #gradle)"() { | ||||
| 	def "build (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "reproducible", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			setProperty('loom.test.reproducible', 'true') | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 			getOutputHash("fabric-example-mod-1.0.0.jar") == modHash | ||||
| 			getOutputHash("fabric-example-mod-1.0.0-sources.jar") in sourceHash // Done for different line endings. | ||||
| 			generateMD5(gradle.getOutputFile("fabric-example-mod-1.0.0.jar")) == modHash | ||||
| 			generateMD5(gradle.getOutputFile("fabric-example-mod-1.0.0-sources.jar")) in sourceHash // Done for different line endings. | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | modHash                               | sourceHash | ||||
| 			version              | modHash                               | sourceHash | ||||
| 			DEFAULT_GRADLE      | "ed3306ef60f434c55048cba8de5dab95"    | ["be31766e6cafbe4ae3bca9e35ba63169", "7348b0bd87d36d7ec6f3bca9c2b66062"] | ||||
| 			PRE_RELEASE_GRADLE  | "ed3306ef60f434c55048cba8de5dab95"    | ["be31766e6cafbe4ae3bca9e35ba63169", "7348b0bd87d36d7ec6f3bca9c2b66062"] | ||||
| 	} | ||||
| 
 | ||||
| 	String getOutputHash(String name) { | ||||
| 		generateMD5(getOutputFile(name)) | ||||
| 	} | ||||
| 
 | ||||
| 	String generateMD5(File file) { | ||||
| 		HashCode hash = Files.asByteSource(file).hash(Hashing.md5()) | ||||
| 		return hash.asBytes().encodeHex() as String | ||||
|  |  | |||
|  | @ -24,25 +24,25 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| // This test runs a mod that exits on mod init | ||||
| class RunConfigTest extends Specification implements ProjectTestTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"runconfigs" | ||||
| 	} | ||||
| 
 | ||||
| class RunConfigTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "#task"() { | ||||
| 	def "Run config #task"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "runconfigs", sharedFiles: true) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create(task) | ||||
| 			def result = gradle.run(task: task) | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":${task}").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			task                | _ | ||||
| 			'runClient'         | _ | ||||
|  |  | |||
|  | @ -24,14 +24,14 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ArchiveAssertionsTrait | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.MockMavenServerTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Stepwise | ||||
| import spock.lang.Unroll | ||||
| import spock.util.environment.RestoreSystemProperties | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static java.lang.System.setProperty | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
|  | @ -39,25 +39,22 @@ import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | |||
|  * This tests publishing signed artifacts to a maven server | ||||
|  */ | ||||
| @Stepwise | ||||
| class SignedProjectTest extends Specification implements MockMavenServerTrait, ArchiveAssertionsTrait { | ||||
| class SignedProjectTest extends Specification implements MockMavenServerTrait, GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	@RestoreSystemProperties | ||||
| 	def "sign and publish lib #gradle"() { | ||||
| 		given: | ||||
| 	def "sign and publish lib #version"() { | ||||
| 		setup: | ||||
| 			setProperty('loom.test.secretKey', PRIVATE_KEY) | ||||
| 			def gradle = gradleProject(project: "signed", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("publish", gradle) | ||||
| 		def result = gradle.run(task: "publish") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":publish").outcome == SUCCESS | ||||
| 		where: | ||||
| 			gradle             | _ | ||||
| 			DEFAULT_GRADLE     | _ | ||||
| 			PRE_RELEASE_GRADLE | _ | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"signed" | ||||
| 		where: | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| 
 | ||||
| 	static final String PRIVATE_KEY = """ | ||||
|  |  | |||
|  | @ -24,36 +24,48 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ArchiveAssertionsTrait | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.ServerRunner | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Timeout | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import java.util.concurrent.TimeUnit | ||||
| 
 | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| 
 | ||||
| class SimpleProjectTest extends Specification implements ProjectTestTrait, ArchiveAssertionsTrait { | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"simple" | ||||
| 	} | ||||
| 
 | ||||
| @Timeout(value = 20, unit = TimeUnit.MINUTES) | ||||
| class SimpleProjectTest extends Specification implements GradleProjectTestTrait { | ||||
| 	@Unroll | ||||
| 	def "build (gradle #gradle)"() { | ||||
| 	def "build and run (gradle #version)"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "simple", version: version) | ||||
| 
 | ||||
| 			def server = ServerRunner.create(gradle.projectDir, "1.16.5") | ||||
| 										.withMod(gradle.getOutputFile("fabric-example-mod-1.0.0.jar")) | ||||
| 										.withFabricApi() | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 			def serverResult = server.run() | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 			getArchiveEntry("fabric-example-mod-1.0.0.jar", "META-INF/MANIFEST.MF").contains("Fabric-Loom-Version: 0.0.0+unknown") | ||||
| 			gradle.getOutputZipEntry("fabric-example-mod-1.0.0.jar", "META-INF/MANIFEST.MF").contains("Fabric-Loom-Version: 0.0.0+unknown") | ||||
| 
 | ||||
| 			serverResult.successful() | ||||
| 			serverResult.output.contains("Hello simple Fabric mod") // A check to ensure our mod init was actually called | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version              | _ | ||||
| 			DEFAULT_GRADLE       | _ | ||||
| 			PRE_RELEASE_GRADLE   | _ | ||||
| 	} | ||||
| 
 | ||||
| 	@Unroll | ||||
| 	def "#ide config generation"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "simple", sharedFiles: true) | ||||
| 		when: | ||||
| 			def result = create(ide) | ||||
| 			def result = gradle.run(task: ide) | ||||
| 		then: | ||||
| 			result.task(":${ide}").outcome == SUCCESS | ||||
| 		where: | ||||
|  |  | |||
|  | @ -24,47 +24,48 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| 
 | ||||
| import org.zeroturnaround.zip.ZipUtil | ||||
| import spock.lang.Specification | ||||
| 
 | ||||
| import java.nio.charset.StandardCharsets | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.* | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class UnpickTest extends Specification implements ProjectTestTrait { | ||||
| class UnpickTest extends Specification implements GradleProjectTestTrait { | ||||
| 	static final String MAPPINGS = "21w13a/net.fabricmc.yarn.21w13a.21w13a+build.30-v2" | ||||
| 
 | ||||
| 	@Override | ||||
| 	String name() { | ||||
| 		"unpick" | ||||
| 	} | ||||
| 
 | ||||
| 	def "unpick decompile"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "unpick", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("genSources", gradle) | ||||
| 			def result = gradle.run(task: "genSources") | ||||
| 		then: | ||||
| 			result.task(":genSources").outcome == SUCCESS | ||||
| 			getClassSource("net/minecraft/block/CakeBlock.java").contains("Block.DEFAULT_SET_BLOCK_STATE_FLAG") | ||||
| 			getClassSource(gradle, "net/minecraft/block/CakeBlock.java").contains("Block.DEFAULT_SET_BLOCK_STATE_FLAG") | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| 
 | ||||
| 	def "unpick build"() { | ||||
| 		setup: | ||||
| 			def gradle = gradleProject(project: "unpick", version: version) | ||||
| 
 | ||||
| 		when: | ||||
| 			def result = create("build", gradle) | ||||
| 			def result = gradle.run(task: "build") | ||||
| 
 | ||||
| 		then: | ||||
| 			result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
| 		where: | ||||
| 			gradle              | _ | ||||
| 			DEFAULT_GRADLE      | _ | ||||
| 			PRE_RELEASE_GRADLE  | _ | ||||
| 			version << STANDARD_TEST_VERSIONS | ||||
| 	} | ||||
| 
 | ||||
| 	String getClassSource(String classname, String mappings = MAPPINGS) { | ||||
| 		File sourcesJar = getGeneratedSources(mappings) | ||||
| 	private static String getClassSource(GradleProject gradle, String classname, String mappings = MAPPINGS) { | ||||
| 		File sourcesJar = gradle.getGeneratedSources(mappings) | ||||
| 		return new String(ZipUtil.unpackEntry(sourcesJar, classname), StandardCharsets.UTF_8) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -33,7 +33,6 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingLayer | |||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec | ||||
| import net.fabricmc.mappingio.format.Tiny2Writer | ||||
| import net.fabricmc.mappingio.tree.MappingTree | ||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree | ||||
| import org.gradle.api.logging.Logger | ||||
| import spock.lang.Specification | ||||
|  |  | |||
|  | @ -31,14 +31,14 @@ interface LayeredMappingsTestConstants { | |||
|     public static final String INTERMEDIARY_1_16_5_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.16.5/intermediary-1.16.5-v2.jar" | ||||
| 
 | ||||
|     public static final Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_17 = [ | ||||
|             client_mappings:new MinecraftVersionMeta.Download(null, "227d16f520848747a59bef6f490ae19dc290a804", 6431705, "https://launcher.mojang.com/v1/objects/227d16f520848747a59bef6f490ae19dc290a804/client.txt"), | ||||
|             server_mappings:new MinecraftVersionMeta.Download(null, "84d80036e14bc5c7894a4fad9dd9f367d3000334", 4948536, "https://launcher.mojang.com/v1/objects/84d80036e14bc5c7894a4fad9dd9f367d3000334/server.txt") | ||||
|             client_mappings: new MinecraftVersionMeta.Download(null, "227d16f520848747a59bef6f490ae19dc290a804", 6431705, "https://launcher.mojang.com/v1/objects/227d16f520848747a59bef6f490ae19dc290a804/client.txt"), | ||||
|             server_mappings: new MinecraftVersionMeta.Download(null, "84d80036e14bc5c7894a4fad9dd9f367d3000334", 4948536, "https://launcher.mojang.com/v1/objects/84d80036e14bc5c7894a4fad9dd9f367d3000334/server.txt") | ||||
|     ] | ||||
|     public static final MinecraftVersionMeta VERSION_META_1_17 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_17, null, null, null, null, 0, null, null, null) | ||||
| 
 | ||||
|     public static final Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_16_5 = [ | ||||
|             client_mappings:new MinecraftVersionMeta.Download(null, "e3dfb0001e1079a1af72ee21517330edf52e6192", 5746047, "https://launcher.mojang.com/v1/objects/e3dfb0001e1079a1af72ee21517330edf52e6192/client.txt"), | ||||
|             server_mappings:new MinecraftVersionMeta.Download(null, "81d5c793695d8cde63afddb40dde88e3a88132ac", 4400926, "https://launcher.mojang.com/v1/objects/81d5c793695d8cde63afddb40dde88e3a88132ac/server.txt") | ||||
|             client_mappings: new MinecraftVersionMeta.Download(null, "e3dfb0001e1079a1af72ee21517330edf52e6192", 5746047, "https://launcher.mojang.com/v1/objects/e3dfb0001e1079a1af72ee21517330edf52e6192/client.txt"), | ||||
|             server_mappings: new MinecraftVersionMeta.Download(null, "81d5c793695d8cde63afddb40dde88e3a88132ac", 4400926, "https://launcher.mojang.com/v1/objects/81d5c793695d8cde63afddb40dde88e3a88132ac/server.txt") | ||||
|     ] | ||||
|     public static final MinecraftVersionMeta VERSION_META_1_16_5 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_16_5, null, null, null, null, 0, null, null, null) | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,7 +27,6 @@ package net.fabricmc.loom.test.unit.layeredmappings | |||
| import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec | ||||
| import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec | ||||
| import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta | ||||
| 
 | ||||
| class ParchmentMappingLayerTest extends LayeredMappingsSpecification { | ||||
|     def "Read parchment mappings" () { | ||||
|  |  | |||
|  | @ -0,0 +1,203 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2021 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.test.util | ||||
| 
 | ||||
| import groovy.transform.Immutable | ||||
| import net.fabricmc.loom.test.LoomTestConstants | ||||
| import org.gradle.testkit.runner.BuildResult | ||||
| import org.gradle.testkit.runner.GradleRunner | ||||
| import org.zeroturnaround.zip.ZipUtil | ||||
| import spock.lang.Shared | ||||
| 
 | ||||
| trait GradleProjectTestTrait { | ||||
|     @Lazy | ||||
|     @Shared | ||||
|     private static File sharedProjectDir = File.createTempDir() | ||||
|     @Lazy | ||||
|     @Shared | ||||
|     private static File sharedGradleHomeDir = File.createTempDir() | ||||
| 
 | ||||
|     GradleProject gradleProject(Map options) { | ||||
|         String gradleVersion = options.version as String ?: LoomTestConstants.DEFAULT_GRADLE | ||||
|         String warningMode = options.warningMode as String ?: "fail" | ||||
|         File projectDir = options.projectDir as File ?: options.sharedFiles ? sharedProjectDir : File.createTempDir() | ||||
|         File gradleHomeDir = options.gradleHomeDir as File ?: options.sharedFiles ? sharedGradleHomeDir : File.createTempDir() | ||||
| 
 | ||||
|         setupProject(options, projectDir) | ||||
| 
 | ||||
|         return new GradleProject( | ||||
|                 gradleVersion: gradleVersion, | ||||
|                 projectDir: projectDir.absolutePath, | ||||
|                 gradleHomeDir: gradleHomeDir.absolutePath, | ||||
|                 warningMode: warningMode | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     private void setupProject(Map options, File projectDir) { | ||||
|         if (options.project) { | ||||
|             copyProjectFromResources(options.project as String, projectDir) | ||||
|             return | ||||
|         } | ||||
| 
 | ||||
|         if (options["repo"]) { | ||||
|             String repo  = options.repo | ||||
|             String commit = options.commit | ||||
| 
 | ||||
|             exec(projectDir, "git", "clone", repo, ".") | ||||
|             exec(projectDir, "git", "checkout", commit) | ||||
| 
 | ||||
|             return | ||||
|         } | ||||
| 
 | ||||
|         throw new UnsupportedOperationException("No project setup method was supplied") | ||||
|     } | ||||
| 
 | ||||
|     private void exec(File projectDir, String... args) { | ||||
|         def process = args.execute([], projectDir) | ||||
|         process.consumeProcessOutput(System.out, System.err) | ||||
| 
 | ||||
|         def exitCode = process.waitFor() | ||||
| 
 | ||||
|         if (exitCode != 0) { | ||||
|              throw new RuntimeException("Command failed with exit code: $exitCode") | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void copyProjectFromResources(String project, File projectDir) { | ||||
|         def projectSourceDir = new File("src/test/resources/projects/$project") | ||||
| 
 | ||||
|         if (!projectSourceDir.exists()) { | ||||
|             throw new FileNotFoundException("Failed to find project directory at: $projectSourceDir.absolutePath") | ||||
|         } | ||||
| 
 | ||||
|         // Cleanup some basic things if they already exists | ||||
|         new File(projectDir, "src").deleteDir() | ||||
|         new File(projectDir, "build.gradle").delete() | ||||
|         new File(projectDir, "settings.gradle").delete() | ||||
| 
 | ||||
|         projectSourceDir.eachFileRecurse { file -> | ||||
|             if (file.isDirectory()) { | ||||
|                 return | ||||
|             } | ||||
| 
 | ||||
|             def path = file.path.replace(projectSourceDir.path, "") | ||||
| 
 | ||||
|             File tempFile = new File(projectDir, path) | ||||
| 
 | ||||
|             if (tempFile.exists()) { | ||||
|                 tempFile.delete() | ||||
|             } | ||||
| 
 | ||||
|             tempFile.parentFile.mkdirs() | ||||
|             tempFile.bytes = file.bytes | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Immutable | ||||
|     static class GradleProject { | ||||
|         private String gradleVersion | ||||
|         private String projectDir | ||||
|         private String gradleHomeDir | ||||
| 
 | ||||
|         private String warningMode | ||||
| 
 | ||||
|         BuildResult run(Map options) { | ||||
|             // Setup the system props to tell loom that its running in a test env | ||||
|             // And override the CI check to ensure that everything is ran | ||||
|             System.setProperty("fabric.loom.test", "true") | ||||
|             System.setProperty("fabric.loom.ci", "false") | ||||
|             System.setProperty("maven.repo.local", new File(getGradleHomeDir(), "m2").absolutePath) | ||||
| 
 | ||||
|             def runner = this.runner | ||||
|             def args = [] | ||||
| 
 | ||||
|             if (options.task) { | ||||
|                 args << options.task | ||||
|             } | ||||
| 
 | ||||
|             args.addAll(options.tasks ?: []) | ||||
| 
 | ||||
|             args << "--stacktrace" | ||||
|             args << "--warning-mode" << warningMode | ||||
|             args << "--gradle-user-home" << gradleHomeDir | ||||
|             args.addAll(options.args ?: []) | ||||
| 
 | ||||
|             runner.withArguments(args as String[]) | ||||
| 
 | ||||
|             return runner.build() | ||||
|         } | ||||
| 
 | ||||
|         private GradleRunner getRunner() { | ||||
|             return GradleRunner.create() | ||||
|                     .withProjectDir(getProjectDir()) | ||||
|                     .withPluginClasspath() | ||||
|                     .withGradleVersion(gradleVersion) | ||||
|                     .forwardOutput() | ||||
|                     .withDebug(true) | ||||
|         } | ||||
| 
 | ||||
|         File getProjectDir() { | ||||
|             return new File(projectDir) | ||||
|         } | ||||
| 
 | ||||
|         File getGradleHomeDir() { | ||||
|             return new File(gradleHomeDir) | ||||
|         } | ||||
| 
 | ||||
|         File getOutputFile(String filename) { | ||||
|             return new File(getProjectDir(), "build/libs/$filename") | ||||
|         } | ||||
| 
 | ||||
|         void printOutputFiles() { | ||||
|             new File(getProjectDir(), "build/libs/").listFiles().each { | ||||
|                 println(it.name) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         File getBuildGradle() { | ||||
|             return new File(getProjectDir(), "build.gradle") | ||||
|         } | ||||
| 
 | ||||
|         String getOutputZipEntry(String filename, String entryName) { | ||||
|             def file = getOutputFile(filename) | ||||
|             def bytes = ZipUtil.unpackEntry(file, entryName) | ||||
| 
 | ||||
|             if (bytes == null) { | ||||
|                 throw new FileNotFoundException("Could not find ${entryName} in ${entryName}") | ||||
|             } | ||||
| 
 | ||||
|             new String(bytes as byte[]) | ||||
|         } | ||||
| 
 | ||||
|         boolean hasOutputZipEntry(String filename, String entryName) { | ||||
|             def file = getOutputFile(filename) | ||||
|             return ZipUtil.unpackEntry(file, entryName) != null | ||||
|         } | ||||
| 
 | ||||
|         File getGeneratedSources(String mappings) { | ||||
|             return new File(getGradleHomeDir(), "caches/fabric-loom/${mappings}/minecraft-mapped-sources.jar") | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -27,7 +27,7 @@ package net.fabricmc.loom.test.util | |||
| import io.javalin.Javalin | ||||
| import org.apache.commons.io.IOUtils | ||||
| 
 | ||||
| trait MockMavenServerTrait extends ProjectTestTrait { | ||||
| trait MockMavenServerTrait { | ||||
|     public final int mavenServerPort = 9876 | ||||
|     public final File testMavenDir = File.createTempDir() | ||||
|     private Javalin server | ||||
|  | @ -74,7 +74,6 @@ trait MockMavenServerTrait extends ProjectTestTrait { | |||
|     @SuppressWarnings('unused') | ||||
|     def cleanupSpec() { | ||||
|         server.stop() | ||||
|         super.cleanupSpec() | ||||
|     } | ||||
| 
 | ||||
|     File getMavenDirectory() { | ||||
|  |  | |||
|  | @ -1,126 +0,0 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016-2021 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.test.util | ||||
| 
 | ||||
| import org.gradle.testkit.runner.BuildResult | ||||
| import org.gradle.testkit.runner.GradleRunner | ||||
| 
 | ||||
| trait ProjectTestTrait { | ||||
| 	final static String DEFAULT_GRADLE = "7.0.1" | ||||
| 	final static String PRE_RELEASE_GRADLE = "7.3-20210724022245+0000" | ||||
| 
 | ||||
| 	static File gradleHome = File.createTempDir() | ||||
| 	File testProjectDir = File.createTempDir() | ||||
| 
 | ||||
| 	abstract String name() | ||||
| 
 | ||||
| 	def copyInputFiles() { | ||||
| 		println "Project directory: ${testProjectDir}" | ||||
| 
 | ||||
| 		def baseProjectDir = new File("src/test/resources/projects/" + name()) | ||||
| 
 | ||||
| 		if (!baseProjectDir.exists()) { | ||||
| 			throw new FileNotFoundException("Failed to find project directory at:" + baseProjectDir.absolutePath) | ||||
| 		} | ||||
| 
 | ||||
| 		baseProjectDir.eachFileRecurse { file -> | ||||
| 			if (file.isDirectory()) { | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
| 			def path = file.path.replace(baseProjectDir.path, "") | ||||
| 
 | ||||
| 			File tempFile = new File(testProjectDir, path) | ||||
| 
 | ||||
| 			if (tempFile.exists()) { | ||||
| 				tempFile.delete() | ||||
| 			} | ||||
| 
 | ||||
| 			tempFile.parentFile.mkdirs() | ||||
| 			tempFile.bytes = file.bytes | ||||
| 		} | ||||
| 
 | ||||
| 		// Disable the CI checks to ensure nothing is skipped | ||||
| 		System.setProperty("fabric.loom.ci", "false") | ||||
| 	} | ||||
| 
 | ||||
| 	@SuppressWarnings('unused') | ||||
| 	def cleanup() { | ||||
| 		// Clean after each test | ||||
| 		new File(testProjectDir, "build").deleteDir() | ||||
| 		new File(testProjectDir, ".gradle").deleteDir() | ||||
| 	} | ||||
| 
 | ||||
| 	@SuppressWarnings('unused') | ||||
| 	def cleanupSpec() { | ||||
| 		testProjectDir.deleteDir() | ||||
| 		gradleHome.deleteDir() | ||||
| 	} | ||||
| 
 | ||||
| 	File buildGradle() { | ||||
| 		return new File(testProjectDir, "build.gradle") | ||||
| 	} | ||||
| 
 | ||||
| 	def filesReady() { | ||||
| 	} | ||||
| 
 | ||||
| 	BuildResult create(String task, String gradleVersion = DEFAULT_GRADLE) { | ||||
| 		System.setProperty("fabric.loom.test", "true") | ||||
| 		copyInputFiles() | ||||
| 		filesReady() | ||||
| 
 | ||||
| 		GradleRunner.create() | ||||
| 			.withProjectDir(testProjectDir) | ||||
| 			.withArguments(task, "--stacktrace", "--warning-mode", warningMode(gradleVersion), "--gradle-user-home", gradleHomeDirectory(gradleVersion)) | ||||
| 			.withPluginClasspath() | ||||
| 			.withGradleVersion(gradleVersion) | ||||
| 			.forwardOutput() | ||||
| 			.withDebug(true) | ||||
| 			.build() | ||||
| 	} | ||||
| 
 | ||||
| 	String warningMode(String gradleVersion) { | ||||
| 		'fail' | ||||
| 	} | ||||
| 
 | ||||
| 	String gradleHomeDirectory(String gradleVersion) { | ||||
| 		// Each gradle version gets its own dir to run on, to ensure that a full run is done. | ||||
| 		new File(gradleHome, gradleVersion).absolutePath | ||||
| 	} | ||||
| 
 | ||||
| 	File getOutputFile(String name, String project = "") { | ||||
| 		def file = new File(testProjectDir, "${project}build/libs/${name}") | ||||
| 
 | ||||
| 		if (!file.exists()) { | ||||
| 			throw new FileNotFoundException("Could not find ${name} at ${file.absolutePath}") | ||||
| 		} | ||||
| 
 | ||||
| 		return file | ||||
| 	} | ||||
| 
 | ||||
| 	File getGeneratedSources(String mappings, String gradleVersion = DEFAULT_GRADLE) { | ||||
| 		return new File(gradleHomeDirectory(gradleVersion), "caches/fabric-loom/${mappings}/minecraft-mapped-sources.jar") | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										208
									
								
								src/test/groovy/net/fabricmc/loom/test/util/ServerRunner.groovy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								src/test/groovy/net/fabricmc/loom/test/util/ServerRunner.groovy
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,208 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016-2021 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.test.util | ||||
| 
 | ||||
| import groovy.transform.Immutable | ||||
| 
 | ||||
| import java.util.concurrent.TimeUnit | ||||
| 
 | ||||
| class ServerRunner { | ||||
|     static final String LOADER_VERSION = "0.11.6" | ||||
|     static final Map<String, String> FABRIC_API_URLS = [ | ||||
|             "1.16.5": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.16/fabric-api-0.37.1+1.16.jar", | ||||
|             "1.17.1": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.17/fabric-api-0.37.1+1.17.jar" | ||||
|     ] | ||||
| 
 | ||||
|     final File serverDir | ||||
|     final String minecraftVersion | ||||
| 
 | ||||
|     final List<File> mods = [] | ||||
| 
 | ||||
|     private ServerRunner(File serverDir, String minecraftVersion) { | ||||
|         this.serverDir = serverDir | ||||
|         this.minecraftVersion = minecraftVersion | ||||
| 
 | ||||
|         this.serverDir.mkdirs() | ||||
|     } | ||||
| 
 | ||||
|     static ServerRunner create(File testProjectDir, String minecraftVersion) { | ||||
|         return new ServerRunner(new File(testProjectDir, "server"), minecraftVersion) | ||||
|     } | ||||
| 
 | ||||
|     def install() { | ||||
|         def args = [ | ||||
|                 "server", | ||||
|                 "-dir", | ||||
|                 serverDir.absolutePath, | ||||
|                 "-mcversion", | ||||
|                 minecraftVersion, | ||||
|                 "-loader", | ||||
|                 LOADER_VERSION, | ||||
|                 "-downloadMinecraft" | ||||
|         ] | ||||
| 
 | ||||
|         //noinspection UnnecessaryQualifiedReference | ||||
|         net.fabricmc.installer.Main.main(args as String[]) | ||||
| 
 | ||||
|         def eulaFile = new File(serverDir, "eula.txt") | ||||
|         eulaFile << "eula=true" | ||||
| 
 | ||||
|         def serverPropsFile = new File(serverDir, "server.properties") | ||||
|         serverPropsFile << "level-type=FLAT" // Generates the world faster | ||||
|     } | ||||
| 
 | ||||
|     ServerRunner withMod(File file) { | ||||
|         mods << file | ||||
|         return this | ||||
|     } | ||||
| 
 | ||||
|     ServerRunner downloadMod(String url, String filename) { | ||||
|         File modFile = new File(serverDir, "downloadedMods/" + filename) | ||||
|         modFile.parentFile.mkdirs() | ||||
| 
 | ||||
|         println("Downloading " + url) | ||||
|         modFile.bytes = new URL(url).bytes | ||||
| 
 | ||||
|         return withMod(modFile) | ||||
|     } | ||||
| 
 | ||||
|     ServerRunner withFabricApi() { | ||||
|         if (!FABRIC_API_URLS[minecraftVersion]) { | ||||
|             throw new UnsupportedOperationException("No Fabric api url for " + minecraftVersion) | ||||
|         } | ||||
| 
 | ||||
|         return downloadMod(FABRIC_API_URLS[minecraftVersion], "fabricapi.jar") | ||||
|     } | ||||
| 
 | ||||
|     ServerRunResult run() { | ||||
|         install() | ||||
| 
 | ||||
|         // Copy the mods here so we can | ||||
|         mods.each { | ||||
|             if (!it.exists()) { | ||||
|                 throw new FileNotFoundException(it.absolutePath) | ||||
|             } | ||||
| 
 | ||||
|             File modFile = new File(serverDir, "mods/" + it.name) | ||||
|             modFile.parentFile.mkdirs() | ||||
|             modFile.bytes = it.bytes | ||||
|         } | ||||
| 
 | ||||
|         String javaExecutablePath = ProcessHandle.current() | ||||
|                 .info() | ||||
|                 .command() | ||||
|                 .orElseThrow() | ||||
| 
 | ||||
|         var builder = new ProcessBuilder() | ||||
|         builder.directory(serverDir) | ||||
|         builder.command(javaExecutablePath, "-Xmx1G", "-jar", "fabric-server-launch.jar", "nogui") | ||||
| 
 | ||||
|         Process process = builder.start() | ||||
|         def out = new StringBuffer() | ||||
|         def isStopping = false | ||||
| 
 | ||||
|         process.consumeProcessOutput( | ||||
|                 new ForwardingAppendable([System.out, out], { | ||||
|                     if (!isStopping && out.contains("Done ") && out.contains("For help, type \"help\"")) { | ||||
|                         isStopping = true | ||||
| 
 | ||||
|                         Thread.start { | ||||
|                             println("Stopping server in 5 seconds") | ||||
|                             sleep(5000) | ||||
| 
 | ||||
|                             println("Sending stop command") | ||||
|                             process.outputStream.withCloseable { | ||||
|                                 it.write("stop\n".bytes) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }), | ||||
|                 new ForwardingAppendable([System.err, out]) | ||||
|         ) | ||||
| 
 | ||||
|         addShutdownHook { | ||||
|             if (process.alive) { | ||||
|                 process.destroy() | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         assert process.waitFor(10, TimeUnit.MINUTES) | ||||
|         int exitCode = process.exitValue() | ||||
| 
 | ||||
|         println("Sever closed with exit code: " + exitCode) | ||||
| 
 | ||||
|         return new ServerRunResult(exitCode, out.toString()) | ||||
|     } | ||||
| 
 | ||||
|     @Immutable | ||||
|     class ServerRunResult { | ||||
|         int exitCode | ||||
|         String output | ||||
| 
 | ||||
|         boolean successful() { | ||||
|             return exitCode == 0 && output.contains("Done ") | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private class ForwardingAppendable implements Appendable { | ||||
|         final List<Appendable> appendables | ||||
|         final Closure onAppended | ||||
| 
 | ||||
|         ForwardingAppendable(List<Appendable> appendables, Closure onAppended = {}) { | ||||
|             this.appendables = appendables | ||||
|             this.onAppended = onAppended | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         Appendable append(CharSequence csq) throws IOException { | ||||
|             appendables.each { | ||||
|                 it.append(csq) | ||||
|             } | ||||
| 
 | ||||
|             onAppended.run() | ||||
|             return this | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         Appendable append(CharSequence csq, int start, int end) throws IOException { | ||||
|             appendables.each { | ||||
|                 it.append(csq, start, end) | ||||
|             } | ||||
| 
 | ||||
|             onAppended.run() | ||||
|             return this | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         Appendable append(char c) throws IOException { | ||||
|             appendables.each { | ||||
|                 it.append(c) | ||||
|             } | ||||
| 
 | ||||
|             onAppended.run() | ||||
|             return this | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -9,6 +9,6 @@ public class ExampleMod implements ModInitializer { | |||
| 		// However, some things (like resources) may still be uninitialized. | ||||
| 		// Proceed with mild caution. | ||||
| 
 | ||||
| 		System.out.println("Hello Fabric world!"); | ||||
| 		System.out.println("Hello simple Fabric mod"); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue