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' | 		exclude module: 'groovy-all' | ||||||
| 	} | 	} | ||||||
| 	testImplementation 'io.javalin:javalin:3.13.9' | 	testImplementation 'io.javalin:javalin:3.13.9' | ||||||
|  | 	testImplementation 'net.fabricmc:fabric-installer:0.7.4' | ||||||
| 
 | 
 | ||||||
| 	compileOnly 'org.jetbrains:annotations:21.0.1' | 	compileOnly 'org.jetbrains:annotations:21.0.1' | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ ruleset { | ||||||
|     SpaceAfterSwitch |     SpaceAfterSwitch | ||||||
|     SpaceAfterWhile |     SpaceAfterWhile | ||||||
|     SpaceAroundClosureArrow |     SpaceAroundClosureArrow | ||||||
|     SpaceAroundMapEntryColon |     SpaceAroundMapEntryColon(characterAfterColonRegex: /\ /) | ||||||
|     SpaceAroundOperator |     SpaceAroundOperator | ||||||
|     SpaceBeforeClosingBrace |     SpaceBeforeClosingBrace | ||||||
|     SpaceBeforeOpeningBrace |     SpaceBeforeOpeningBrace | ||||||
|  | @ -61,6 +61,13 @@ ruleset { | ||||||
|     FieldTypeRequired |     FieldTypeRequired | ||||||
|     MethodParameterTypeRequired |     MethodParameterTypeRequired | ||||||
| 
 | 
 | ||||||
|  |     // Imports | ||||||
|  |     UnusedImport | ||||||
|  |     UnnecessaryGroovyImport | ||||||
|  |     NoWildcardImports(ignoreStaticImports: true) | ||||||
|  |     ImportFromSamePackage | ||||||
|  |     DuplicateImport | ||||||
|  | 
 | ||||||
|     //Misc |     //Misc | ||||||
|     LongLiteralWithLowerCaseL |     LongLiteralWithLowerCaseL | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ import java.io.IOException; | ||||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
|  | import java.util.Collections; | ||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| import java.util.stream.Stream; | import java.util.stream.Stream; | ||||||
|  | @ -36,6 +37,7 @@ import java.util.stream.StreamSupport; | ||||||
| import java.util.zip.ZipEntry; | import java.util.zip.ZipEntry; | ||||||
| import java.util.zip.ZipFile; | import java.util.zip.ZipFile; | ||||||
| 
 | 
 | ||||||
|  | import com.google.gson.JsonArray; | ||||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||||
| import com.google.gson.JsonPrimitive; | import com.google.gson.JsonPrimitive; | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
|  | @ -108,7 +110,13 @@ public final class MixinRefmapHelper { | ||||||
| 
 | 
 | ||||||
| 	@NotNull | 	@NotNull | ||||||
| 	private static Collection<String> getMixinConfigurationFiles(JsonObject fabricModJson) { | 	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 -> { | 				.map(e -> { | ||||||
| 					if (e instanceof JsonPrimitive str) { | 					if (e instanceof JsonPrimitive str) { | ||||||
| 						return str.getAsString(); | 						return str.getAsString(); | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { | ||||||
| 	protected void addDependencies(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) { | 	protected void addDependencies(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) { | ||||||
| 		if (jarProcessorManager.isInvalid(projectMappedJar) || isRefreshDeps()) { | 		if (jarProcessorManager.isInvalid(projectMappedJar) || isRefreshDeps()) { | ||||||
| 			getProject().getLogger().info(":processing mapped jar"); | 			getProject().getLogger().info(":processing mapped jar"); | ||||||
| 			invalidateJars(); | 			invalidateJar(); | ||||||
| 
 | 
 | ||||||
| 			try { | 			try { | ||||||
| 				FileUtils.copyFile(super.getMappedJar(), projectMappedJar); | 				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())); | 				getProject().getDependencies().module("net.minecraft:minecraft-" + projectMappedClassifier + ":" + getMinecraftProvider().minecraftVersion() + "/" + getExtension().getMappingsProvider().mappingsIdentifier())); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void invalidateJars() { | 	private void invalidateJar() { | ||||||
| 		File dir = projectMappedJar.getParentFile(); | 		if (projectMappedJar.exists()) { | ||||||
| 
 | 			getProject().getLogger().warn("Invalidating project jar"); | ||||||
| 		if (dir.exists()) { |  | ||||||
| 			getProject().getLogger().warn("Invalidating project jars"); |  | ||||||
| 
 | 
 | ||||||
| 			try { | 			try { | ||||||
| 				FileUtils.cleanDirectory(dir); | 				FileUtils.forceDelete(projectMappedJar); | ||||||
| 			} catch (IOException e) { | 			} 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). |  * 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 |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  * of this software and associated documentation files (the "Software"), to deal |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  | @ -22,25 +22,11 @@ | ||||||
|  * SOFTWARE. |  * 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 { |     public final static String[] STANDARD_TEST_VERSIONS = [DEFAULT_GRADLE, PRE_RELEASE_GRADLE] | ||||||
| 	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 |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | @ -24,30 +24,25 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.ProjectTestTrait |  | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class AccessWidenerTest extends Specification implements ProjectTestTrait, ArchiveAssertionsTrait { | class AccessWidenerTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"accesswidener" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "accesswidener (gradle #gradle)"() { | 	def "accesswidener (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "accesswidener", version: version) | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			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: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	String expected() { | 	String expected() { | ||||||
|  |  | ||||||
|  | @ -24,42 +24,36 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class CustomManifestTest extends Specification implements ProjectTestTrait { | class CustomManifestTest extends Specification implements GradleProjectTestTrait { | ||||||
|     @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" |  | ||||||
|             } |  | ||||||
|         ''' |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Unroll |     @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: |         when: | ||||||
|             def result = create("build", gradle) |             def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
|         then: |         then: | ||||||
|             result.task(":build").outcome == SUCCESS |             result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
|         where: |         where: | ||||||
|             gradle              | _ |             version << STANDARD_TEST_VERSIONS | ||||||
|             DEFAULT_GRADLE      | _ |  | ||||||
|             PRE_RELEASE_GRADLE  | _ |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,28 +24,27 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class DecompileTest extends Specification implements ProjectTestTrait { | class DecompileTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"decompile" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "#decompiler gradle #gradle"() { | 	def "#decompiler gradle #version"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "decompile", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create(task, gradle) | 			def result = gradle.run(task: task) | ||||||
| 
 | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":${task}").outcome == SUCCESS | 			result.task(":${task}").outcome == SUCCESS | ||||||
| 
 | 
 | ||||||
| 		where: | 		where: | ||||||
| 			decompiler 		| task								| gradle | 			decompiler 		| task								| version | ||||||
| 			'fernflower'	| "genSources"						| DEFAULT_GRADLE | 			'fernflower'	| "genSources"						| DEFAULT_GRADLE | ||||||
| 			'fernflower'	| "genSources"						| PRE_RELEASE_GRADLE | 			'fernflower'	| "genSources"						| PRE_RELEASE_GRADLE | ||||||
| 			'cfr' 			| "genSourcesWithExperimentalCfr"	| DEFAULT_GRADLE | 			'cfr' 			| "genSourcesWithExperimentalCfr"	| DEFAULT_GRADLE | ||||||
|  |  | ||||||
|  | @ -24,29 +24,27 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class DependencyResolutionManagementTest extends Specification implements ProjectTestTrait { | class DependencyResolutionManagementTest extends Specification implements GradleProjectTestTrait { | ||||||
|     @Override |  | ||||||
|     String name() { |  | ||||||
|         "dependencyResolutionManagement" |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Unroll |     @Unroll | ||||||
|     def "build (gradle #gradle)"() { |     def "build (gradle #version)"() { | ||||||
|  |         setup: | ||||||
|  |             def gradle = gradleProject(project: "dependencyResolutionManagement", version: version) | ||||||
|  | 
 | ||||||
|         when: |         when: | ||||||
|             def result = create("build", gradle) |             def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
|         then: |         then: | ||||||
|             result.task(":basic:build").outcome == SUCCESS |             result.task(":basic:build").outcome == SUCCESS | ||||||
|             result.task(":projmap:build").outcome == SUCCESS |             result.task(":projmap:build").outcome == SUCCESS | ||||||
| 
 | 
 | ||||||
|         where: |         where: | ||||||
|         gradle              | _ |             version << STANDARD_TEST_VERSIONS | ||||||
|         DEFAULT_GRADLE      | _ |  | ||||||
|         PRE_RELEASE_GRADLE  | _ |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,38 +24,34 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class ExperimentalVersionsTest extends Specification implements ProjectTestTrait { | class ExperimentalVersionsTest extends Specification implements GradleProjectTestTrait { | ||||||
|     @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" |  | ||||||
|             } |  | ||||||
|         ''' |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Unroll |     @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: |         when: | ||||||
|             def result = create("build", gradle) |             def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
|         then: |         then: | ||||||
|             result.task(":build").outcome == SUCCESS |             result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
|         where: |         where: | ||||||
|             gradle              | _ |             version << STANDARD_TEST_VERSIONS | ||||||
|             DEFAULT_GRADLE      | _ |  | ||||||
|             PRE_RELEASE_GRADLE  | _ |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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 | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class Java16ProjectTest extends Specification implements ProjectTestTrait { | class Java16ProjectTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"java16" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "build (gradle #gradle)"() { | 	def "build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "java16", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,28 +24,26 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | package net.fabricmc.loom.test.integration | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.test.util.ProjectTestTrait | import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||||
| import spock.lang.IgnoreIf |  | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class KotlinTest extends Specification implements ProjectTestTrait { | class KotlinTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"kotlin" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "kotlin build (gradle #gradle)"() { | 	def "kotlin build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "kotlin", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,24 +24,27 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| // This test uses gradle 4.9 and 1.14.4 v1 mappings | // This test uses gradle 4.9 and 1.14.4 v1 mappings | ||||||
| class LegacyProjectTest extends Specification implements ProjectTestTrait { | class LegacyProjectTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"legacy" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "build"() { | 	def "legacy build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "legacy", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", DEFAULT_GRADLE) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
|  | 		where: | ||||||
|  | 			version << STANDARD_TEST_VERSIONS | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,27 +24,26 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class LocalFileDependencyTest extends Specification implements ProjectTestTrait { | class LocalFileDependencyTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"localFileDependency" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "build (gradle #gradle)"() { | 	def "build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "localFileDependency", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,13 +24,14 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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 net.fabricmc.loom.test.util.MockMavenServerTrait | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
| import spock.lang.Stepwise | import spock.lang.Stepwise | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| import spock.util.environment.RestoreSystemProperties | import spock.util.environment.RestoreSystemProperties | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static java.lang.System.setProperty | import static java.lang.System.setProperty | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | 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 |  * This tests publishing a range of versions and then tries to resolve and build against them | ||||||
|  */ |  */ | ||||||
| @Stepwise | @Stepwise | ||||||
| class MavenProjectTest extends Specification implements MockMavenServerTrait, ArchiveAssertionsTrait { | class MavenProjectTest extends Specification implements MockMavenServerTrait, GradleProjectTestTrait { | ||||||
| 	@RestoreSystemProperties | 	@RestoreSystemProperties | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "publish lib #version #gradle"() { | 	def "publish lib #version #gradleVersion"() { | ||||||
| 		given: | 		setup: | ||||||
| 			setProperty('loom.test.version', version) | 			setProperty('loom.test.version', version) | ||||||
| 			library = true | 			def gradle = gradleProject(project: "mavenLibrary", version: gradleVersion, sharedFiles: true) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("publish", gradle) | 			def result = gradle.run(tasks: ["clean", "publish"]) | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":publish").outcome == SUCCESS | 			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: | 		where: | ||||||
| 			version           | gradle | 			version           | gradleVersion | ||||||
| 			'1.0.0'           | DEFAULT_GRADLE | 			'1.0.0'           | DEFAULT_GRADLE | ||||||
| 			'1.0.0'           | PRE_RELEASE_GRADLE | 			'1.0.0'           | PRE_RELEASE_GRADLE | ||||||
| 			'1.1.0'           | DEFAULT_GRADLE | 			'1.1.0'           | DEFAULT_GRADLE | ||||||
|  | @ -64,17 +68,20 @@ class MavenProjectTest extends Specification implements MockMavenServerTrait, Ar | ||||||
| 
 | 
 | ||||||
| 	@RestoreSystemProperties | 	@RestoreSystemProperties | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "resolve #version #gradle"() { | 	def "resolve #version #gradleVersion"() { | ||||||
| 		given: | 		given: | ||||||
| 			setProperty('loom.test.resolve', "com.example:fabric-example-lib:${version}") | 			setProperty('loom.test.resolve', "com.example:fabric-example-lib:${version}") | ||||||
| 			library = false | 			def gradle = gradleProject(project: "maven", version: gradleVersion, sharedFiles: true) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(tasks: ["clean", "build"]) | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			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: | 		where: | ||||||
| 			version                      | gradle | 			version                      | gradleVersion | ||||||
| 			'1.0.0'                      | DEFAULT_GRADLE | 			'1.0.0'                      | DEFAULT_GRADLE | ||||||
| 			'1.0.0'                      | PRE_RELEASE_GRADLE | 			'1.0.0'                      | PRE_RELEASE_GRADLE | ||||||
| 			'1.1.+'                      | DEFAULT_GRADLE | 			'1.1.+'                      | DEFAULT_GRADLE | ||||||
|  | @ -87,12 +94,4 @@ class MavenProjectTest extends Specification implements MockMavenServerTrait, Ar | ||||||
| 			'2.0.0-SNAPSHOT:classifier'  | DEFAULT_GRADLE | 			'2.0.0-SNAPSHOT:classifier'  | DEFAULT_GRADLE | ||||||
| 			'master-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 | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||||
| import java.util.jar.JarFile | import java.util.jar.JarFile | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class MixinApAutoRefmapTest extends Specification implements ProjectTestTrait { | class MixinApAutoRefmapTest extends Specification implements GradleProjectTestTrait { | ||||||
|     @Override |  | ||||||
|     String name() { |  | ||||||
|         "mixinApAutoRefmap" |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Unroll |     @Unroll | ||||||
|     def "build (gradle #gradle)"() { |     def "build (gradle #version)"() { | ||||||
|  |         setup: | ||||||
|  |             def gradle = gradleProject(project: "mixinApAutoRefmap", version: version) | ||||||
|  | 
 | ||||||
|         when: |         when: | ||||||
|         def result = create("build", gradle) |             def result = gradle.run(task: "build") | ||||||
| 
 | 
 | ||||||
|         then: |         then: | ||||||
|         result.task(":build").outcome == SUCCESS |             result.task(":build").outcome == SUCCESS | ||||||
| 
 | 
 | ||||||
|         // verify the ref-map name is correctly generated |             // verify the ref-map name is correctly generated | ||||||
|         def jar = new JarFile(getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile) |             def jar = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile) | ||||||
|         jar.getEntry("refmap0000.json") == null |             jar.getEntry("refmap0000.json") == null | ||||||
|         jar.getEntry("refmap0001.json") != null |             jar.getEntry("refmap0001.json") != null | ||||||
|         jar.getEntry("refmap0002.json") != null |             jar.getEntry("refmap0002.json") != null | ||||||
|         jar.getEntry("refmap0003.json") != null |             jar.getEntry("refmap0003.json") != null | ||||||
| 
 | 
 | ||||||
|         def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json")))) |             def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json")))) | ||||||
|         j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json" |             j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json" | ||||||
| 
 | 
 | ||||||
|         def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json")))) |             def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json")))) | ||||||
|         j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json" |             j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json" | ||||||
| 
 | 
 | ||||||
|         def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json")))) |             def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json")))) | ||||||
|         j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json" |             j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json" | ||||||
| 
 | 
 | ||||||
|         def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json")))) |             def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json")))) | ||||||
|         !j4.asJsonObject.has("refmap") |             !j4.asJsonObject.has("refmap") | ||||||
| 
 | 
 | ||||||
|         def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json")))) |             def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json")))) | ||||||
|         !j5.asJsonObject.has("refmap") |             !j5.asJsonObject.has("refmap") | ||||||
| 
 | 
 | ||||||
|         where: |         where: | ||||||
|         gradle              | _ |             version << STANDARD_TEST_VERSIONS | ||||||
|         DEFAULT_GRADLE      | _ |  | ||||||
|         PRE_RELEASE_GRADLE  | _ |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,40 +24,38 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
| import java.util.jar.JarFile | import java.util.jar.JarFile | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class MixinApSimpleTest extends Specification implements ProjectTestTrait { | class MixinApSimpleTest extends Specification implements GradleProjectTestTrait { | ||||||
|     @Override |  | ||||||
|     String name() { |  | ||||||
|         "mixinApSimple" |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Unroll |     @Unroll | ||||||
|     def "build (gradle #gradle)"() { |     def "build (gradle #version)"() { | ||||||
|  |         setup: | ||||||
|  |             def gradle = gradleProject(project: "mixinApSimple", version: version) | ||||||
|  | 
 | ||||||
|         when: |         when: | ||||||
|         def result = create("build", gradle) |             def result = gradle.run(task: "build") | ||||||
| 
 | 
 | ||||||
|         then: |         then: | ||||||
|         result.task(":build").outcome == SUCCESS |             result.task(":build").outcome == SUCCESS | ||||||
| 
 | 
 | ||||||
|         // verify the ref-map name is correctly generated |             // verify the ref-map name is correctly generated | ||||||
|         def main = new JarFile(getOutputFile("fabric-example-mod-1.0.0-dev.jar").absoluteFile) |             def main = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-dev.jar").absoluteFile) | ||||||
|         main.getEntry("main-refmap0000.json") != null |             main.getEntry("main-refmap0000.json") != null | ||||||
|         def mixin = new JarFile(getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile) |             def mixin = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile) | ||||||
|         mixin.getEntry("default-refmap0000.json") != null |             mixin.getEntry("default-refmap0000.json") != null | ||||||
|         def mixin1 = new JarFile(getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile) |             def mixin1 = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile) | ||||||
|         mixin1.getEntry("main-refmap0000.json") == null |             mixin1.getEntry("main-refmap0000.json") == null | ||||||
|         mixin1.getEntry("default-refmap0000.json") == null |             mixin1.getEntry("default-refmap0000.json") == null | ||||||
| 
 | 
 | ||||||
|         where: |         where: | ||||||
|         gradle              | _ |             version << STANDARD_TEST_VERSIONS | ||||||
|         DEFAULT_GRADLE      | _ |  | ||||||
|         PRE_RELEASE_GRADLE  | _ |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,27 +24,26 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class MojangMappingsProjectTest extends Specification implements ProjectTestTrait { | class MojangMappingsProjectTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"mojangMappings" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "build (gradle #gradle)"() { | 	def "build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "mojangMappings", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,23 +24,22 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.ProjectTestTrait |  | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class MultiProjectTest extends Specification implements ProjectTestTrait, ArchiveAssertionsTrait { | class MultiProjectTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"multiproject" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "build (gradle #gradle)"() { | 	def "build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "multiproject", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
| 			result.task(":core: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(":remapAllJars").outcome == SUCCESS | ||||||
| 			result.task(":remapAllSources").outcome == SUCCESS | 			result.task(":remapAllSources").outcome == SUCCESS | ||||||
| 
 | 
 | ||||||
| 			hasArchiveEntry("multiproject-1.0.0.jar", "META-INF/jars/example-1.0.0.jar") | 			gradle.hasOutputZipEntry("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") | 			gradle.hasOutputZipEntry("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/fabric-api-base-0.2.1+9354966b7d.jar") | ||||||
| 
 | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,29 +24,26 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class ParchmentTest extends Specification implements ProjectTestTrait { | class ParchmentTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"parchment" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "parchment #gradle"() { | 	def "parchment #version"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "parchment", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
| 
 | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
| 
 | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -27,40 +27,37 @@ package net.fabricmc.loom.test.integration | ||||||
| import com.google.common.hash.HashCode | import com.google.common.hash.HashCode | ||||||
| import com.google.common.hash.Hashing | import com.google.common.hash.Hashing | ||||||
| import com.google.common.io.Files | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| import spock.util.environment.RestoreSystemProperties | import spock.util.environment.RestoreSystemProperties | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static java.lang.System.setProperty | import static java.lang.System.setProperty | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| class ReproducibleBuildTest extends Specification implements ProjectTestTrait { | class ReproducibleBuildTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"reproducible" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@RestoreSystemProperties | 	@RestoreSystemProperties | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "build (gradle #gradle)"() { | 	def "build (gradle #version)"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "reproducible", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			setProperty('loom.test.reproducible', 'true') | 			setProperty('loom.test.reproducible', 'true') | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
| 			getOutputHash("fabric-example-mod-1.0.0.jar") == modHash | 			generateMD5(gradle.getOutputFile("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-sources.jar")) in sourceHash // Done for different line endings. | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | modHash                               | sourceHash | 			version              | modHash                               | sourceHash | ||||||
| 			DEFAULT_GRADLE      | "ed3306ef60f434c55048cba8de5dab95"    | ["be31766e6cafbe4ae3bca9e35ba63169", "7348b0bd87d36d7ec6f3bca9c2b66062"] | 			DEFAULT_GRADLE      | "ed3306ef60f434c55048cba8de5dab95"    | ["be31766e6cafbe4ae3bca9e35ba63169", "7348b0bd87d36d7ec6f3bca9c2b66062"] | ||||||
| 			PRE_RELEASE_GRADLE  | "ed3306ef60f434c55048cba8de5dab95"    | ["be31766e6cafbe4ae3bca9e35ba63169", "7348b0bd87d36d7ec6f3bca9c2b66062"] | 			PRE_RELEASE_GRADLE  | "ed3306ef60f434c55048cba8de5dab95"    | ["be31766e6cafbe4ae3bca9e35ba63169", "7348b0bd87d36d7ec6f3bca9c2b66062"] | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	String getOutputHash(String name) { |  | ||||||
| 		generateMD5(getOutputFile(name)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	String generateMD5(File file) { | 	String generateMD5(File file) { | ||||||
| 		HashCode hash = Files.asByteSource(file).hash(Hashing.md5()) | 		HashCode hash = Files.asByteSource(file).hash(Hashing.md5()) | ||||||
| 		return hash.asBytes().encodeHex() as String | 		return hash.asBytes().encodeHex() as String | ||||||
|  |  | ||||||
|  | @ -24,25 +24,25 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.Specification | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
| 
 | 
 | ||||||
| // This test runs a mod that exits on mod init | // This test runs a mod that exits on mod init | ||||||
| class RunConfigTest extends Specification implements ProjectTestTrait { | class RunConfigTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"runconfigs" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "#task"() { | 	def "Run config #task"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "runconfigs", sharedFiles: true) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create(task) | 			def result = gradle.run(task: task) | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":${task}").outcome == SUCCESS | 			result.task(":${task}").outcome == SUCCESS | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			task                | _ | 			task                | _ | ||||||
| 			'runClient'         | _ | 			'runClient'         | _ | ||||||
|  |  | ||||||
|  | @ -24,14 +24,14 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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 net.fabricmc.loom.test.util.MockMavenServerTrait | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
| import spock.lang.Stepwise | import spock.lang.Stepwise | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| import spock.util.environment.RestoreSystemProperties | import spock.util.environment.RestoreSystemProperties | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static java.lang.System.setProperty | import static java.lang.System.setProperty | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | 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 |  * This tests publishing signed artifacts to a maven server | ||||||
|  */ |  */ | ||||||
| @Stepwise | @Stepwise | ||||||
| class SignedProjectTest extends Specification implements MockMavenServerTrait, ArchiveAssertionsTrait { | class SignedProjectTest extends Specification implements MockMavenServerTrait, GradleProjectTestTrait { | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	@RestoreSystemProperties | 	@RestoreSystemProperties | ||||||
| 	def "sign and publish lib #gradle"() { | 	def "sign and publish lib #version"() { | ||||||
| 		given: | 		setup: | ||||||
| 			setProperty('loom.test.secretKey', PRIVATE_KEY) | 			setProperty('loom.test.secretKey', PRIVATE_KEY) | ||||||
|  | 			def gradle = gradleProject(project: "signed", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("publish", gradle) | 		def result = gradle.run(task: "publish") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":publish").outcome == SUCCESS | 			result.task(":publish").outcome == SUCCESS | ||||||
| 		where: |  | ||||||
| 			gradle             | _ |  | ||||||
| 			DEFAULT_GRADLE     | _ |  | ||||||
| 			PRE_RELEASE_GRADLE | _ |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	@Override | 		where: | ||||||
| 	String name() { | 			version << STANDARD_TEST_VERSIONS | ||||||
| 		"signed" |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static final String PRIVATE_KEY = """ | 	static final String PRIVATE_KEY = """ | ||||||
|  |  | ||||||
|  | @ -24,36 +24,48 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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.ProjectTestTrait | import net.fabricmc.loom.test.util.ServerRunner | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
|  | import spock.lang.Timeout | ||||||
| import spock.lang.Unroll | import spock.lang.Unroll | ||||||
| 
 | 
 | ||||||
|  | import java.util.concurrent.TimeUnit | ||||||
|  | 
 | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| 
 | 
 | ||||||
| class SimpleProjectTest extends Specification implements ProjectTestTrait, ArchiveAssertionsTrait { | @Timeout(value = 20, unit = TimeUnit.MINUTES) | ||||||
| 	@Override | class SimpleProjectTest extends Specification implements GradleProjectTestTrait { | ||||||
| 	String name() { |  | ||||||
| 		"simple" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Unroll | 	@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: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 			def serverResult = server.run() | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			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: | 		where: | ||||||
| 			gradle              | _ | 			version              | _ | ||||||
| 			DEFAULT_GRADLE      | _ | 			DEFAULT_GRADLE       | _ | ||||||
| 			PRE_RELEASE_GRADLE  | _ | 			PRE_RELEASE_GRADLE   | _ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Unroll | 	@Unroll | ||||||
| 	def "#ide config generation"() { | 	def "#ide config generation"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "simple", sharedFiles: true) | ||||||
| 		when: | 		when: | ||||||
| 			def result = create(ide) | 			def result = gradle.run(task: ide) | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":${ide}").outcome == SUCCESS | 			result.task(":${ide}").outcome == SUCCESS | ||||||
| 		where: | 		where: | ||||||
|  |  | ||||||
|  | @ -24,47 +24,48 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.test.integration | 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 org.zeroturnaround.zip.ZipUtil | ||||||
| import spock.lang.Specification | import spock.lang.Specification | ||||||
| 
 | 
 | ||||||
| import java.nio.charset.StandardCharsets | import java.nio.charset.StandardCharsets | ||||||
| 
 | 
 | ||||||
|  | import static net.fabricmc.loom.test.LoomTestConstants.* | ||||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | 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" | 	static final String MAPPINGS = "21w13a/net.fabricmc.yarn.21w13a.21w13a+build.30-v2" | ||||||
| 
 | 
 | ||||||
| 	@Override |  | ||||||
| 	String name() { |  | ||||||
| 		"unpick" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	def "unpick decompile"() { | 	def "unpick decompile"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "unpick", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("genSources", gradle) | 			def result = gradle.run(task: "genSources") | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":genSources").outcome == SUCCESS | 			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: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	def "unpick build"() { | 	def "unpick build"() { | ||||||
|  | 		setup: | ||||||
|  | 			def gradle = gradleProject(project: "unpick", version: version) | ||||||
|  | 
 | ||||||
| 		when: | 		when: | ||||||
| 			def result = create("build", gradle) | 			def result = gradle.run(task: "build") | ||||||
|  | 
 | ||||||
| 		then: | 		then: | ||||||
| 			result.task(":build").outcome == SUCCESS | 			result.task(":build").outcome == SUCCESS | ||||||
|  | 
 | ||||||
| 		where: | 		where: | ||||||
| 			gradle              | _ | 			version << STANDARD_TEST_VERSIONS | ||||||
| 			DEFAULT_GRADLE      | _ |  | ||||||
| 			PRE_RELEASE_GRADLE  | _ |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	String getClassSource(String classname, String mappings = MAPPINGS) { | 	private static String getClassSource(GradleProject gradle, String classname, String mappings = MAPPINGS) { | ||||||
| 		File sourcesJar = getGeneratedSources(mappings) | 		File sourcesJar = gradle.getGeneratedSources(mappings) | ||||||
| 		return new String(ZipUtil.unpackEntry(sourcesJar, classname), StandardCharsets.UTF_8) | 		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.MappingsProvider | ||||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec | import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec | ||||||
| import net.fabricmc.mappingio.format.Tiny2Writer | import net.fabricmc.mappingio.format.Tiny2Writer | ||||||
| import net.fabricmc.mappingio.tree.MappingTree |  | ||||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree | import net.fabricmc.mappingio.tree.MemoryMappingTree | ||||||
| import org.gradle.api.logging.Logger | import org.gradle.api.logging.Logger | ||||||
| import spock.lang.Specification | 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 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 = [ |     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"), |             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") |             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 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 = [ |     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"), |             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") |             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) |     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.intermediary.IntermediaryMappingsSpec | ||||||
| import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec | import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec | ||||||
| import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec | import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec | ||||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta |  | ||||||
| 
 | 
 | ||||||
| class ParchmentMappingLayerTest extends LayeredMappingsSpecification { | class ParchmentMappingLayerTest extends LayeredMappingsSpecification { | ||||||
|     def "Read parchment mappings" () { |     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 io.javalin.Javalin | ||||||
| import org.apache.commons.io.IOUtils | import org.apache.commons.io.IOUtils | ||||||
| 
 | 
 | ||||||
| trait MockMavenServerTrait extends ProjectTestTrait { | trait MockMavenServerTrait { | ||||||
|     public final int mavenServerPort = 9876 |     public final int mavenServerPort = 9876 | ||||||
|     public final File testMavenDir = File.createTempDir() |     public final File testMavenDir = File.createTempDir() | ||||||
|     private Javalin server |     private Javalin server | ||||||
|  | @ -74,7 +74,6 @@ trait MockMavenServerTrait extends ProjectTestTrait { | ||||||
|     @SuppressWarnings('unused') |     @SuppressWarnings('unused') | ||||||
|     def cleanupSpec() { |     def cleanupSpec() { | ||||||
|         server.stop() |         server.stop() | ||||||
|         super.cleanupSpec() |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     File getMavenDirectory() { |     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. | 		// However, some things (like resources) may still be uninitialized. | ||||||
| 		// Proceed with mild caution. | 		// Proceed with mild caution. | ||||||
| 
 | 
 | ||||||
| 		System.out.println("Hello Fabric world!"); | 		System.out.println("Hello simple Fabric mod"); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue