Reformat groovy code (#850)

* Reformat groovy

* Also format gradle files

* Groovy import order
This commit is contained in:
modmuss50
2023-03-31 10:22:58 +01:00
committed by GitHub
parent b506a6280a
commit ad7d4e75b9
88 changed files with 2431 additions and 2299 deletions

View File

@@ -147,7 +147,14 @@ spotless {
}
groovy {
importOrder('java', 'javax', '', 'net.fabricmc', '\\#')
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-")
greclipse()
}
groovyGradle {
target 'src/**/*.gradle', '*.gradle'
greclipse()
}
kotlin {
@@ -290,7 +297,7 @@ task writeActionsTestMatrix() {
// Disabled for CI, as it fails too much.
if (className.endsWith("DecompileTest")) return
testMatrix.add("net.fabricmc.loom.test.integration.${className}")
testMatrix.add("net.fabricmc.loom.test.integration.${className}")
}
}
@@ -318,9 +325,9 @@ task downloadGradleSources() {
doLast {
// Awful hack to find the gradle api location
def gradleApiFile = project.configurations.detachedConfiguration(dependencies.gradleApi()).files.stream()
.filter {
it.name.startsWith("gradle-api")
}.findFirst().orElseThrow()
.filter {
it.name.startsWith("gradle-api")
}.findFirst().orElseThrow()
def gradleApiSources = new File(gradleApiFile.absolutePath.replace(".jar", "-sources.jar"))
def url = "https://services.gradle.org/distributions/gradle-${GradleVersion.current().getVersion()}-src.zip"

View File

@@ -27,28 +27,32 @@ package net.fabricmc.loom.test
import org.gradle.util.GradleVersion
class LoomTestConstants {
private final static String NIGHTLY_VERSION = "8.1-20230217231705+0000"
private final static boolean NIGHTLY_EXISTS = nightlyExists(NIGHTLY_VERSION)
private final static String NIGHTLY_VERSION = "8.1-20230217231705+0000"
private final static boolean NIGHTLY_EXISTS = nightlyExists(NIGHTLY_VERSION)
// Test against the version of Gradle being used to build loom
public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion()
public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion()
// Test against Gradle 8
public final static String GRADLE_8 = "8.0.1"
// Tests that depend specifically on the nightly will run on the current version when the nightly is not available.
public final static String PRE_RELEASE_GRADLE = NIGHTLY_EXISTS ? NIGHTLY_VERSION : DEFAULT_GRADLE
// Tests that depend specifically on the nightly will run on the current version when the nightly is not available.
public final static String PRE_RELEASE_GRADLE = NIGHTLY_EXISTS ? NIGHTLY_VERSION : DEFAULT_GRADLE
// Randomly sorted to ensure that all versions can run with a clean gradle home.
public final static String[] STANDARD_TEST_VERSIONS = (NIGHTLY_EXISTS ? [DEFAULT_GRADLE, GRADLE_8, PRE_RELEASE_GRADLE] : [DEFAULT_GRADLE, GRADLE_8]).shuffled().toArray()
public final static String[] STANDARD_TEST_VERSIONS = (NIGHTLY_EXISTS ? [
DEFAULT_GRADLE,
GRADLE_8,
PRE_RELEASE_GRADLE
] : [DEFAULT_GRADLE, GRADLE_8]).shuffled().toArray()
public static final File TEST_DIR = new File("./.gradle/test-files")
/**
* Nightly gradle versions get removed after a certain amount of time, lets check to see if its still online before running the tests.
*/
private static boolean nightlyExists(String version) {
def url = "https://services.gradle.org/distributions-snapshots/gradle-${version}-bin.zip"
def con = new URL(url).openConnection() as HttpURLConnection
con.setRequestMethod("HEAD") // No need to request the whole file.
/**
* Nightly gradle versions get removed after a certain amount of time, lets check to see if its still online before running the tests.
*/
private static boolean nightlyExists(String version) {
def url = "https://services.gradle.org/distributions-snapshots/gradle-${version}-bin.zip"
def con = new URL(url).openConnection() as HttpURLConnection
con.setRequestMethod("HEAD") // No need to request the whole file.
return con.getResponseCode() == HttpURLConnection.HTTP_OK
}
return con.getResponseCode() == HttpURLConnection.HTTP_OK
}
}

View File

@@ -26,6 +26,7 @@ package net.fabricmc.loom.test.benchmark
import groovy.time.TimeCategory
import groovy.time.TimeDuration
import net.fabricmc.loom.test.LoomTestConstants
import net.fabricmc.loom.test.util.GradleProjectTestTrait
@@ -35,31 +36,40 @@ import net.fabricmc.loom.test.util.GradleProjectTestTrait
*/
@Singleton
class FabricAPIBenchmark implements GradleProjectTestTrait {
def run(File dir) {
def gradle = gradleProject(
version: LoomTestConstants.DEFAULT_GRADLE,
projectDir: new File(dir, "project"),
gradleHomeDir: new File(dir, "gradlehome"),
allowExistingRepo: true,
def run(File dir) {
def gradle = gradleProject(
version: LoomTestConstants.DEFAULT_GRADLE,
projectDir: new File(dir, "project"),
gradleHomeDir: new File(dir, "gradlehome"),
allowExistingRepo: true,
repo: "https://github.com/FabricMC/fabric.git",
commit: "2facd446984085376bd23245410ebf2dc0881b02",
patch: "fabric_api"
)
repo: "https://github.com/FabricMC/fabric.git",
commit: "2facd446984085376bd23245410ebf2dc0881b02",
patch: "fabric_api"
)
gradle.enableMultiProjectOptimisation()
def timeStart = new Date()
def timeStart = new Date()
def result = gradle.run(tasks: ["clean", "build", "-x", "test", "-x", "check", "-x", ":fabric-data-generation-api-v1:runDatagen"], args: [])
def result = gradle.run(tasks: [
"clean",
"build",
"-x",
"test",
"-x",
"check",
"-x",
":fabric-data-generation-api-v1:runDatagen"
], args: [])
def timeStop = new Date()
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
println(duration)
}
def timeStop = new Date()
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
println(duration)
}
static void main(String[] args) {
getInstance().run(new File(args[0]))
System.exit(0)
}
static void main(String[] args) {
getInstance().run(new File(args[0]))
System.exit(0)
}
}

View File

@@ -26,6 +26,7 @@ package net.fabricmc.loom.test.benchmark
import groovy.time.TimeCategory
import groovy.time.TimeDuration
import net.fabricmc.loom.test.LoomTestConstants
import net.fabricmc.loom.test.util.GradleProjectTestTrait
@@ -37,18 +38,18 @@ import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
*/
@Singleton
class SimpleBenchmark implements GradleProjectTestTrait {
def run(File dir) {
// Forces loom to refresh files
System.setProperty("loom.refresh", "true")
def run(File dir) {
// Forces loom to refresh files
System.setProperty("loom.refresh", "true")
def gradle = gradleProject(
project: "minimalBase",
version: LoomTestConstants.PRE_RELEASE_GRADLE,
projectDir: new File(dir, "project"),
gradleHomeDir: new File(dir, "gradlehome")
)
def gradle = gradleProject(
project: "minimalBase",
version: LoomTestConstants.PRE_RELEASE_GRADLE,
projectDir: new File(dir, "project"),
gradleHomeDir: new File(dir, "gradlehome")
)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18.1"
mappings "net.fabricmc:yarn:1.18.1+build.17:v2"
@@ -56,20 +57,20 @@ class SimpleBenchmark implements GradleProjectTestTrait {
}
'''
def timeStart = new Date()
def timeStart = new Date()
def result = gradle.run(tasks: ["clean", "build"])
def result = gradle.run(tasks: ["clean", "build"])
def timeStop = new Date()
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
println(duration)
def timeStop = new Date()
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
println(duration)
assert result.task(":build").outcome == SUCCESS
assert result.task(":build").outcome == SUCCESS
System.exit(0)
}
System.exit(0)
}
static void main(String[] args) {
getInstance().run(new File(args[0]))
}
static void main(String[] args) {
getInstance().run(new File(args[0]))
}
}

View File

@@ -24,11 +24,12 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -36,14 +37,14 @@ class AccessWidenerTest extends Specification implements GradleProjectTestTrait
@Unroll
def "accesswidener (gradle #version)"() {
setup:
def gradle = gradleProject(project: "accesswidener", version: version)
def gradle = gradleProject(project: "accesswidener", version: version)
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
gradle.getOutputZipEntry("fabric-example-mod-1.0.0.jar", "modid.accesswidener") == expected().replaceAll('\r', '')
result.task(":build").outcome == SUCCESS
gradle.getOutputZipEntry("fabric-example-mod-1.0.0.jar", "modid.accesswidener") == expected().replaceAll('\r', '')
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
String expected() {
@@ -53,36 +54,36 @@ class AccessWidenerTest extends Specification implements GradleProjectTestTrait
@Unroll
def "transitive accesswidener (gradle #version)"() {
setup:
def gradle = gradleProject(project: "transitiveAccesswidener", version: version)
ZipUtils.pack(new File(gradle.projectDir, "dummyDependency").toPath(), new File(gradle.projectDir, "dummy.jar").toPath())
def gradle = gradleProject(project: "transitiveAccesswidener", version: version)
ZipUtils.pack(new File(gradle.projectDir, "dummyDependency").toPath(), new File(gradle.projectDir, "dummy.jar").toPath())
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "invalid (#awLine)"() {
setup:
def gradle = gradleProject(project: "accesswidener", version: version)
new File(gradle.projectDir, "src/main/resources/modid.accesswidener").append(awLine)
def errorPrefix = "Failed to validate access-widener file modid.accesswidener on line 10: java.lang.RuntimeException: "
def gradle = gradleProject(project: "accesswidener", version: version)
new File(gradle.projectDir, "src/main/resources/modid.accesswidener").append(awLine)
def errorPrefix = "Failed to validate access-widener file modid.accesswidener on line 10: java.lang.RuntimeException: "
when:
def result = gradle.run(task: "check", expectFailure: true)
def result = gradle.run(task: "check", expectFailure: true)
then:
result.output.contains(errorPrefix + error)
result.output.contains(errorPrefix + error)
where:
awLine | error | version
'accessible\tclass\tnet/minecraft/DoesntExists' | "Could not find class (net/minecraft/DoesntExists)" | DEFAULT_GRADLE
'accessible\tfield\tnet/minecraft/screen/slot/Slot\tabc\tI' | "Could not find field (abcI) in class (net/minecraft/screen/slot/Slot)" | DEFAULT_GRADLE
'accessible\tmethod\tnet/minecraft/client/main/Main\tmain\t([Ljava/lang/NotAString;)V' | "Could not find method (main([Ljava/lang/NotAString;)V) in class (net/minecraft/client/main/Main)" | DEFAULT_GRADLE
awLine | error | version
'accessible\tclass\tnet/minecraft/DoesntExists' | "Could not find class (net/minecraft/DoesntExists)" | DEFAULT_GRADLE
'accessible\tfield\tnet/minecraft/screen/slot/Slot\tabc\tI' | "Could not find field (abcI) in class (net/minecraft/screen/slot/Slot)" | DEFAULT_GRADLE
'accessible\tmethod\tnet/minecraft/client/main/Main\tmain\t([Ljava/lang/NotAString;)V' | "Could not find method (main([Ljava/lang/NotAString;)V) in class (net/minecraft/client/main/Main)" | DEFAULT_GRADLE
}
}

View File

@@ -24,19 +24,20 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class CustomManifestTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "customManifest (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
@Unroll
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"
}
@@ -47,13 +48,13 @@ class CustomManifestTest extends Specification implements GradleProjectTestTrait
modImplementation "net.fabricmc:fabric-loader:0.11.6"
}
'''
when:
def result = gradle.run(task: "build")
when:
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,41 +36,41 @@ class DecompileTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "#decompiler gradle #version"() {
setup:
def gradle = gradleProject(project: "decompile", version: version)
def gradle = gradleProject(project: "decompile", version: version)
when:
def result = gradle.run(task: task)
def result = gradle.run(task: task)
then:
result.task(":${task}").outcome == SUCCESS
result.task(":${task}").outcome == SUCCESS
where:
decompiler | task | version
'fernflower' | "genSourcesWithFernFlower" | PRE_RELEASE_GRADLE
'cfr' | "genSourcesWithCfr" | PRE_RELEASE_GRADLE
decompiler | task | version
'fernflower' | "genSourcesWithFernFlower" | PRE_RELEASE_GRADLE
'cfr' | "genSourcesWithCfr" | PRE_RELEASE_GRADLE
}
@Unroll
def "custom decompiler (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildSrc("decompile")
gradle.buildGradle << '''
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildSrc("decompile")
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18.1"
mappings "net.fabricmc:yarn:1.18.1+build.18:v2"
}
'''
when:
def result = gradle.run(task: "genSourcesWithCustom")
def result = gradle.run(task: "genSourcesWithCustom")
then:
result.task(":genSourcesWithCustom").outcome == SUCCESS
result.task(":preDecompile").outcome == SUCCESS
result.output.contains("Writing test file")
result.output.contains("Running custom decompiler")
result.task(":genSourcesWithCustom").outcome == SUCCESS
result.task(":preDecompile").outcome == SUCCESS
result.output.contains("Writing test file")
result.output.contains("Running custom decompiler")
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,23 +24,24 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class DependencyOrderTest extends Specification implements GradleProjectTestTrait {
// Regression test for a bug introduced in 1.1 development where
// if Fabric Loader is resolved after another mod dependency,
// Gradle will crash because loaderLibraries has been resolved before
// Loader's dependencies have been added to it.
@Unroll
def "build with loader as the second dependency (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << """
// Regression test for a bug introduced in 1.1 development where
// if Fabric Loader is resolved after another mod dependency,
// Gradle will crash because loaderLibraries has been resolved before
// Loader's dependencies have been added to it.
@Unroll
def "build with loader as the second dependency (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << """
dependencies {
minecraft 'com.mojang:minecraft:1.19.3'
mappings 'net.fabricmc:yarn:1.19.3+build.5:v2'
@@ -48,11 +49,11 @@ class DependencyOrderTest extends Specification implements GradleProjectTestTrai
modImplementation 'net.fabricmc:fabric-loader:0.14.13'
}
""".stripIndent()
when:
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
when:
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,27 +24,28 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class DependencyResolutionManagementTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "dependencyResolutionManagement", version: version)
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "dependencyResolutionManagement", version: version)
when:
def result = gradle.run(task: "build")
when:
def result = gradle.run(task: "build")
then:
result.task(":basic:build").outcome == SUCCESS
result.task(":projmap:build").outcome == SUCCESS
then:
result.task(":basic:build").outcome == SUCCESS
result.task(":projmap:build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,20 +24,21 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class ExperimentalVersionsTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "experimental versions (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@Unroll
def "experimental versions (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18_experimental-snapshot-1"
mappings "net.fabricmc:yarn:1.18_experimental-snapshot-1+build.2:v2"
@@ -45,13 +46,13 @@ class ExperimentalVersionsTest extends Specification implements GradleProjectTes
}
'''
when:
def result = gradle.run(task: "build")
when:
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,13 +24,14 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.ServerRunner
import java.util.concurrent.TimeUnit
import spock.lang.Specification
import spock.lang.Timeout
import spock.lang.Unroll
import java.util.concurrent.TimeUnit
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.ServerRunner
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -42,36 +43,47 @@ class FabricAPITest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build and run (gradle #version)"() {
setup:
def gradle = gradleProject(
repo: "https://github.com/FabricMC/fabric.git",
commit: "2facd446984085376bd23245410ebf2dc0881b02",
version: version,
patch: "fabric_api"
)
def gradle = gradleProject(
repo: "https://github.com/FabricMC/fabric.git",
commit: "2facd446984085376bd23245410ebf2dc0881b02",
version: version,
patch: "fabric_api"
)
gradle.enableMultiProjectOptimisation()
gradle.enableMultiProjectOptimisation()
// Set the version to something constant
gradle.buildGradle.text = gradle.buildGradle.text.replace('project.version + "+" + (ENV.GITHUB_RUN_NUMBER ? "" : "local-") + getBranch()', "\"$API_VERSION\"")
// Set the version to something constant
gradle.buildGradle.text = gradle.buildGradle.text.replace('project.version + "+" + (ENV.GITHUB_RUN_NUMBER ? "" : "local-") + getBranch()', "\"$API_VERSION\"")
def server = ServerRunner.create(gradle.projectDir, "1.19.3")
.withMod(gradle.getOutputFile("fabric-api-${API_VERSION}.jar"))
def server = ServerRunner.create(gradle.projectDir, "1.19.3")
.withMod(gradle.getOutputFile("fabric-api-${API_VERSION}.jar"))
when:
def result = gradle.run(tasks: ["build", "publishToMavenLocal"], args: ["--parallel", "-x", "check", "-x", "runDatagen", "-x", "runGametest"]) // Note: checkstyle does not appear to like being ran in a test runner
gradle.printOutputFiles()
def result = gradle.run(tasks: [
"build",
"publishToMavenLocal"
], args: [
"--parallel",
"-x",
"check",
"-x",
"runDatagen",
"-x",
"runGametest"
]) // Note: checkstyle does not appear to like being ran in a test runner
gradle.printOutputFiles()
def serverResult = server.run()
def serverResult = server.run()
then:
result.task(":build").outcome == SUCCESS
result.task(":prepareRemapJar").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
result.task(":prepareRemapJar").outcome == SUCCESS
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/12.1.0/fabric-biome-api-v1-12.1.0.jar").exists()
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/12.1.0/fabric-biome-api-v1-12.1.0-sources.jar").exists()
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/12.1.0/fabric-biome-api-v1-12.1.0.jar").exists()
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/12.1.0/fabric-biome-api-v1-12.1.0-sources.jar").exists()
serverResult.successful()
serverResult.output.contains("- fabric-api $API_VERSION")
serverResult.successful()
serverResult.output.contains("- fabric-api $API_VERSION")
where:
//version << STANDARD_TEST_VERSIONS
version << [DEFAULT_GRADLE]
//version << STANDARD_TEST_VERSIONS
version << [DEFAULT_GRADLE]
}
}

View File

@@ -24,11 +24,12 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -36,16 +37,16 @@ class InterfaceInjectionTest extends Specification implements GradleProjectTestT
@Unroll
def "interface injection (gradle #version)"() {
setup:
def gradle = gradleProject(project: "interfaceInjection", version: version)
ZipUtils.pack(new File(gradle.projectDir, "dummyDependency").toPath(), new File(gradle.projectDir, "dummy.jar").toPath())
def gradle = gradleProject(project: "interfaceInjection", version: version)
ZipUtils.pack(new File(gradle.projectDir, "dummyDependency").toPath(), new File(gradle.projectDir, "dummy.jar").toPath())
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,15 +36,15 @@ class Java16ProjectTest extends Specification implements GradleProjectTestTrait
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "java16", version: version)
def gradle = gradleProject(project: "java16", version: version)
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,11 +24,12 @@
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.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.ServerRunner
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -36,27 +37,30 @@ class KotlinTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "kotlin build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "kotlin", version: version)
def server = ServerRunner.create(gradle.projectDir, "1.16.5")
def gradle = gradleProject(project: "kotlin", version: version)
def server = ServerRunner.create(gradle.projectDir, "1.16.5")
.withMod(gradle.getOutputFile("fabric-example-mod-0.0.1.jar"))
.downloadMod(ServerRunner.FABRIC_LANG_KOTLIN, "fabric-language-kotlin-1.8.7+kotlin.1.7.22.jar")
when:
def result = gradle.run(tasks: ["build", "publishToMavenLocal"])
def serverResult = server.run()
def result = gradle.run(tasks: [
"build",
"publishToMavenLocal"
])
def serverResult = server.run()
then:
result.task(":build").outcome == SUCCESS
serverResult.successful()
result.task(":build").outcome == SUCCESS
serverResult.successful()
// Check POM file to see that it doesn't contain transitive deps of FLK.
// See https://github.com/FabricMC/fabric-loom/issues/572.
result.task(":publishToMavenLocal").outcome == SUCCESS
def pom = new File(gradle.projectDir, "build/publications/mavenKotlin/pom-default.xml").text
// FLK depends on kotlin-reflect unlike our test project.
pom.contains('kotlin-reflect') == false
// Check POM file to see that it doesn't contain transitive deps of FLK.
// See https://github.com/FabricMC/fabric-loom/issues/572.
result.task(":publishToMavenLocal").outcome == SUCCESS
def pom = new File(gradle.projectDir, "build/publications/mavenKotlin/pom-default.xml").text
// FLK depends on kotlin-reflect unlike our test project.
pom.contains('kotlin-reflect') == false
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.PRE_RELEASE_GRADLE
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -36,23 +37,23 @@ class LegacyProjectTest extends Specification implements GradleProjectTestTrait
@Unroll
def "legacy build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "legacy", version: version)
def gradle = gradleProject(project: "legacy", version: version)
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "Unsupported minecraft (minecraft #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE)
gradle.buildGradle << """
def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE)
gradle.buildGradle << """
loom {
noIntermediateMappings()
}
@@ -68,28 +69,28 @@ class LegacyProjectTest extends Specification implements GradleProjectTestTrait
"""
when:
def result = gradle.run(task: "configureClientLaunch")
def result = gradle.run(task: "configureClientLaunch")
then:
result.task(":configureClientLaunch").outcome == SUCCESS
result.task(":configureClientLaunch").outcome == SUCCESS
where:
version | _
'1.13.2' | _
'1.12.2' | _
'1.8.9' | _
'1.7.10' | _
'1.7' | _
'1.6.4' | _
'1.4.7' | _
'1.3.2' | _
version | _
'1.13.2' | _
'1.12.2' | _
'1.8.9' | _
'1.7.10' | _
'1.7' | _
'1.6.4' | _
'1.4.7' | _
'1.3.2' | _
}
@Unroll
def "Ancient minecraft (minecraft #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE)
gradle.buildGradle << """
def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE)
gradle.buildGradle << """
loom {
noIntermediateMappings()
clientOnlyMinecraftJar()
@@ -106,15 +107,15 @@ class LegacyProjectTest extends Specification implements GradleProjectTestTrait
"""
when:
def result = gradle.run(task: "configureClientLaunch")
def result = gradle.run(task: "configureClientLaunch")
then:
result.task(":configureClientLaunch").outcome == SUCCESS
result.task(":configureClientLaunch").outcome == SUCCESS
where:
version | _
'1.2.5' | _
'b1.8.1' | _
'a1.2.5' | _
version | _
'1.2.5' | _
'b1.8.1' | _
'a1.2.5' | _
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,15 +36,15 @@ class LocalFileDependencyTest extends Specification implements GradleProjectTest
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "localFileDependency", version: version)
def gradle = gradleProject(project: "localFileDependency", version: version)
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,19 +36,22 @@ class LocalRuntimeTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "localRuntime", version: version)
def gradle = gradleProject(project: "localRuntime", version: version)
when:
def result = gradle.run(tasks: ["build", "publishToMavenLocal"])
def result = gradle.run(tasks: [
"build",
"publishToMavenLocal"
])
then:
result.task(":build").outcome == SUCCESS
def pomFile = new File(gradle.getProjectDir(), "build/publications/mavenJava/pom-default.xml")
def pom = pomFile.text
!pom.contains("fabric-api")
!pom.contains("enigma")
result.task(":build").outcome == SUCCESS
def pomFile = new File(gradle.getProjectDir(), "build/publications/mavenJava/pom-default.xml")
def pom = pomFile.text
!pom.contains("fabric-api")
!pom.contains("enigma")
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,20 +24,21 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class MCJarConfigTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "server only (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@Unroll
def "server only (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
loom {
serverOnlyMinecraftJar()
}
@@ -49,22 +50,22 @@ class MCJarConfigTest extends Specification implements GradleProjectTestTrait {
}
'''
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "client only (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@Unroll
def "client only (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
loom {
clientOnlyMinecraftJar()
}
@@ -76,22 +77,22 @@ class MCJarConfigTest extends Specification implements GradleProjectTestTrait {
}
'''
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "split (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@Unroll
def "split (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
loom {
splitMinecraftJar()
}
@@ -103,22 +104,22 @@ class MCJarConfigTest extends Specification implements GradleProjectTestTrait {
}
'''
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "split env (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@Unroll
def "split env (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
loom {
splitEnvironmentSourceSets()
}
@@ -130,13 +131,13 @@ class MCJarConfigTest extends Specification implements GradleProjectTestTrait {
}
'''
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
when:
def result = gradle.run(tasks: ["build", "ideaSyncTask"])
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,15 +24,16 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.MockMavenServerTrait
import spock.lang.Specification
import spock.lang.Stepwise
import spock.lang.Unroll
import spock.util.environment.RestoreSystemProperties
import static net.fabricmc.loom.test.LoomTestConstants.*
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.MockMavenServerTrait
import static java.lang.System.setProperty
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
/**
@@ -44,55 +45,55 @@ class MavenProjectTest extends Specification implements MockMavenServerTrait, Gr
@Unroll
def "publish lib #version #gradleVersion"() {
setup:
setProperty('loom.test.version', version)
def gradle = gradleProject(project: "mavenLibrary", version: gradleVersion, sharedFiles: true)
setProperty('loom.test.version', version)
def gradle = gradleProject(project: "mavenLibrary", version: gradleVersion, sharedFiles: true)
when:
def result = gradle.run(tasks: ["clean", "publish"])
def result = gradle.run(tasks: ["clean", "publish"])
then:
result.task(":publish").outcome == SUCCESS
gradle.hasOutputZipEntry("fabric-example-lib-${version}.jar", "net/fabricmc/example/ExampleLib.class")
gradle.hasOutputZipEntry("fabric-example-lib-${version}-sources.jar", "net/fabricmc/example/ExampleLib.java")
result.task(":publish").outcome == SUCCESS
gradle.hasOutputZipEntry("fabric-example-lib-${version}.jar", "net/fabricmc/example/ExampleLib.class")
gradle.hasOutputZipEntry("fabric-example-lib-${version}-sources.jar", "net/fabricmc/example/ExampleLib.java")
where:
version | gradleVersion
'1.0.0' | DEFAULT_GRADLE
'1.0.0' | PRE_RELEASE_GRADLE
'1.1.0' | DEFAULT_GRADLE
'1.1.1' | DEFAULT_GRADLE
'1.2.0+meta' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT' | DEFAULT_GRADLE // Publish this twice to give ourselves a bit of a challenge
'master-SNAPSHOT' | DEFAULT_GRADLE
version | gradleVersion
'1.0.0' | DEFAULT_GRADLE
'1.0.0' | PRE_RELEASE_GRADLE
'1.1.0' | DEFAULT_GRADLE
'1.1.1' | DEFAULT_GRADLE
'1.2.0+meta' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT' | DEFAULT_GRADLE // Publish this twice to give ourselves a bit of a challenge
'master-SNAPSHOT' | DEFAULT_GRADLE
}
@RestoreSystemProperties
@Unroll
def "resolve #version #gradleVersion"() {
given:
setProperty('loom.test.resolve', "com.example:fabric-example-lib:${version}")
def gradle = gradleProject(project: "maven", version: gradleVersion, sharedFiles: true)
setProperty('loom.test.resolve', "com.example:fabric-example-lib:${version}")
def gradle = gradleProject(project: "maven", version: gradleVersion, sharedFiles: true)
when:
def result = gradle.run(tasks: ["clean", "build"])
def result = gradle.run(tasks: ["clean", "build"])
then:
result.task(":build").outcome == SUCCESS
gradle.hasOutputZipEntry("fabric-example-mod-1.0.0.jar", "net/fabricmc/examplemod/ExampleMod.class")
result.task(":build").outcome == SUCCESS
gradle.hasOutputZipEntry("fabric-example-mod-1.0.0.jar", "net/fabricmc/examplemod/ExampleMod.class")
where:
version | gradleVersion
'1.0.0' | DEFAULT_GRADLE
'1.0.0' | PRE_RELEASE_GRADLE
'1.1.+' | DEFAULT_GRADLE
'1.2.0+meta' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT' | DEFAULT_GRADLE
'master-SNAPSHOT' | DEFAULT_GRADLE
'1.0.0:classifier' | DEFAULT_GRADLE
'1.1.+:classifier' | DEFAULT_GRADLE
'1.2.0+meta:classifier' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT:classifier' | DEFAULT_GRADLE
'master-SNAPSHOT:classifier' | DEFAULT_GRADLE
version | gradleVersion
'1.0.0' | DEFAULT_GRADLE
'1.0.0' | PRE_RELEASE_GRADLE
'1.1.+' | DEFAULT_GRADLE
'1.2.0+meta' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT' | DEFAULT_GRADLE
'master-SNAPSHOT' | DEFAULT_GRADLE
'1.0.0:classifier' | DEFAULT_GRADLE
'1.1.+:classifier' | DEFAULT_GRADLE
'1.2.0+meta:classifier' | DEFAULT_GRADLE
'2.0.0-SNAPSHOT:classifier' | DEFAULT_GRADLE
'master-SNAPSHOT:classifier' | DEFAULT_GRADLE
}
}

View File

@@ -24,27 +24,32 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class MigrateMappingsTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "Migrate mappings (gradle #version)"() {
setup:
def gradle = gradleProject(project: "java16", version: version)
@Unroll
def "Migrate mappings (gradle #version)"() {
setup:
def gradle = gradleProject(project: "java16", version: version)
when:
def result = gradle.run(tasks: ["migrateMappings", "--mappings", "21w38a+build.10"])
when:
def result = gradle.run(tasks: [
"migrateMappings",
"--mappings",
"21w38a+build.10"
])
then:
result.task(":migrateMappings").outcome == SUCCESS
// TODO check it actually did something
then:
result.task(":migrateMappings").outcome == SUCCESS
// TODO check it actually did something
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,53 +24,55 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import java.util.jar.JarFile
import com.google.gson.JsonParser
import spock.lang.Specification
import spock.lang.Unroll
import com.google.gson.JsonParser
import java.util.jar.JarFile
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class MixinApAutoRefmapTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "mixinApAutoRefmap", version: version)
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "mixinApAutoRefmap", version: version)
when:
def result = gradle.run(task: "build")
when:
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
// verify the ref-map name is correctly generated
def jar = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile)
jar.getEntry("refmap0000.json") == null
jar.getEntry("refmap0001.json") != null
jar.getEntry("refmap0002.json") != null
jar.getEntry("refmap0003.json") != null
// verify the ref-map name is correctly generated
def jar = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile)
jar.getEntry("refmap0000.json") == null
jar.getEntry("refmap0001.json") != null
jar.getEntry("refmap0002.json") != null
jar.getEntry("refmap0003.json") != null
def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json"))))
j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json"
def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json"))))
j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json"
def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json"))))
j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json"
def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json"))))
j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json"
def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json"))))
j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json"
def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json"))))
j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json"
def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json"))))
!j4.asJsonObject.has("refmap")
def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json"))))
!j4.asJsonObject.has("refmap")
def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json"))))
!j5.asJsonObject.has("refmap")
def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json"))))
!j5.asJsonObject.has("refmap")
def j6 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("subfolder/subfolder.mixins.json"))))
j6.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json"
def j6 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("subfolder/subfolder.mixins.json"))))
j6.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json"
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,38 +24,38 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import java.util.jar.JarFile
import spock.lang.Specification
import spock.lang.Unroll
import java.util.jar.JarFile
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class MixinApSimpleTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "mixinApSimple", version: version)
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "mixinApSimple", version: version)
when:
def result = gradle.run(task: "build")
when:
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
// verify the ref-map name is correctly generated
def main = new JarFile(new File(gradle.projectDir, "build/devlibs/fabric-example-mod-1.0.0-dev.jar").absoluteFile)
main.getEntry("main-refmap0000.json") != null
def mixin = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile)
mixin.getEntry("default-refmap0000.json") != null
def mixin1 = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile)
mixin1.getEntry("main-refmap0000.json") == null
mixin1.getEntry("default-refmap0000.json") == null
// verify the ref-map name is correctly generated
def main = new JarFile(new File(gradle.projectDir, "build/devlibs/fabric-example-mod-1.0.0-dev.jar").absoluteFile)
main.getEntry("main-refmap0000.json") != null
def mixin = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile)
mixin.getEntry("default-refmap0000.json") != null
def mixin1 = new JarFile(gradle.getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile)
mixin1.getEntry("main-refmap0000.json") == null
mixin1.getEntry("default-refmap0000.json") == null
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,12 +24,13 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import java.nio.charset.StandardCharsets
import spock.lang.Specification
import spock.lang.Unroll
import java.nio.charset.StandardCharsets
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -38,21 +39,21 @@ class ModJavadocTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "mod javadoc (gradle #version)"() {
setup:
def gradle = gradleProject(project: "modJavadoc", version: version)
ZipUtils.pack(new File(gradle.projectDir, "dummyDependency").toPath(), new File(gradle.projectDir, "dummy.jar").toPath())
def gradle = gradleProject(project: "modJavadoc", version: version)
ZipUtils.pack(new File(gradle.projectDir, "dummyDependency").toPath(), new File(gradle.projectDir, "dummy.jar").toPath())
when:
def result = gradle.run(task: "genSources")
def blocks = getClassSource(gradle, "net/minecraft/block/Blocks.java")
def result = gradle.run(task: "genSources")
def blocks = getClassSource(gradle, "net/minecraft/block/Blocks.java")
then:
result.task(":genSources").outcome == SUCCESS
blocks.contains("An example of a mod added class javadoc")
blocks.contains("An example of a mod added field javadoc")
blocks.contains("An example of a mod added method javadoc")
result.task(":genSources").outcome == SUCCESS
blocks.contains("An example of a mod added class javadoc")
blocks.contains("An example of a mod added field javadoc")
blocks.contains("An example of a mod added method javadoc")
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
private static String getClassSource(GradleProject gradle, String classname) {

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,26 +36,26 @@ class MojangMappingsProjectTest extends Specification implements GradleProjectTe
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "mojangMappings", version: version)
def gradle = gradleProject(project: "mojangMappings", version: version)
when:
def result = gradle.run(task: "build")
def dependenciesResult = gradle.run(task: "dependencies")
def result = gradle.run(task: "build")
def dependenciesResult = gradle.run(task: "dependencies")
then:
result.task(":build").outcome == SUCCESS
dependenciesResult.task(":dependencies").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
dependenciesResult.task(":dependencies").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "mojang mappings without synthetic field names (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18-pre5"
mappings loom.layered {
@@ -66,21 +67,21 @@ class MojangMappingsProjectTest extends Specification implements GradleProjectTe
'''
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "fail with wrong officialMojangMappings usage (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18.2"
mappings loom.layered {
@@ -91,12 +92,12 @@ class MojangMappingsProjectTest extends Specification implements GradleProjectTe
'''
when:
def result = gradle.run(task: "build", expectFailure: true)
def result = gradle.run(task: "build", expectFailure: true)
then:
result.output.contains("Use `officialMojangMappings()` when configuring layered mappings, not the extension method `loom.officialMojangMappings()`")
result.output.contains("Use `officialMojangMappings()` when configuring layered mappings, not the extension method `loom.officialMojangMappings()`")
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,27 +36,32 @@ class MultiMcVersionTest extends Specification implements GradleProjectTestTrait
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "multi-mc-versions", version: version)
def gradle = gradleProject(project: "multi-mc-versions", version: version)
when:
def result = gradle.run(tasks: "build")
def result = gradle.run(tasks: "build")
then:
def versions = [
'fabric-1.14.4',
'fabric-1.15', 'fabric-1.15.2',
'fabric-1.16', 'fabric-1.16.5',
'fabric-1.17', 'fabric-1.17.1',
'fabric-1.18', 'fabric-1.18.2',
'fabric-1.19', 'fabric-1.19.3'
]
def versions = [
'fabric-1.14.4',
'fabric-1.15',
'fabric-1.15.2',
'fabric-1.16',
'fabric-1.16.5',
'fabric-1.17',
'fabric-1.17.1',
'fabric-1.18',
'fabric-1.18.2',
'fabric-1.19',
'fabric-1.19.3'
]
result.task(":build").outcome == SUCCESS
versions.forEach {
result.task(":$it:build").outcome == SUCCESS
}
result.task(":build").outcome == SUCCESS
versions.forEach {
result.task(":$it:build").outcome == SUCCESS
}
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,21 +36,26 @@ class MultiProjectTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "multiproject", version: version)
def gradle = gradleProject(project: "multiproject", version: version)
when:
def result = gradle.run(tasks: ["build", "eclipse", "vscode", "idea"])
def result = gradle.run(tasks: [
"build",
"eclipse",
"vscode",
"idea"
])
then:
result.task(":build").outcome == SUCCESS
result.task(":core:build").outcome == SUCCESS
result.task(":example:build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
result.task(":core:build").outcome == SUCCESS
result.task(":example:build").outcome == SUCCESS
gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/example-1.0.0.jar")
gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/core-1.0.0.jar")
gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/fabric-api-base-0.2.1+9354966b7d.jar")
gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/example-1.0.0.jar")
gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/core-1.0.0.jar")
gradle.hasOutputZipEntry("multiproject-1.0.0.jar", "META-INF/jars/fabric-api-base-0.2.1+9354966b7d.jar")
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,73 +24,74 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import spock.util.environment.RestoreSystemProperties
import net.fabricmc.loom.test.util.GradleProjectTestTrait
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.UP_TO_DATE
class NativesTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "Default natives for 1.18 (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@Unroll
def "Default natives for 1.18 (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18"
mappings loom.officialMojangMappings()
}
'''
when:
// Run the task twice to ensure its up to date
def result = gradle.run(task: "extractNatives")
def result2 = gradle.run(task: "extractNatives")
when:
// Run the task twice to ensure its up to date
def result = gradle.run(task: "extractNatives")
def result2 = gradle.run(task: "extractNatives")
then:
result.task(":extractNatives").outcome == SUCCESS
result2.task(":extractNatives").outcome == UP_TO_DATE
then:
result.task(":extractNatives").outcome == SUCCESS
result2.task(":extractNatives").outcome == UP_TO_DATE
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
@RestoreSystemProperties
@Unroll
def "Overridden natives for 1.18 (gradle #version)"() {
setup:
System.setProperty('loom.test.lwjgloverride', "true")
def gradle = gradleProject(project: "minimalBase", version: version)
@RestoreSystemProperties
@Unroll
def "Overridden natives for 1.18 (gradle #version)"() {
setup:
System.setProperty('loom.test.lwjgloverride', "true")
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18"
mappings loom.officialMojangMappings()
}
'''
when:
// Run the task twice to ensure its up to date
def result = gradle.run(task: "extractNatives")
when:
// Run the task twice to ensure its up to date
def result = gradle.run(task: "extractNatives")
then:
result.task(":extractNatives").outcome == SUCCESS
then:
result.task(":extractNatives").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
@RestoreSystemProperties
@Unroll
def "1.19 classpath natives (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
@RestoreSystemProperties
@Unroll
def "1.19 classpath natives (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
loom {
noIntermediateMappings()
}
@@ -103,14 +104,14 @@ class NativesTest extends Specification implements GradleProjectTestTrait {
}
'''
when:
// Run the task twice to ensure its up to date
def result = gradle.run(task: "build")
when:
// Run the task twice to ensure its up to date
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -35,15 +36,15 @@ class ParchmentTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "parchment #version"() {
setup:
def gradle = gradleProject(project: "parchment", version: version)
def gradle = gradleProject(project: "parchment", version: version)
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -27,13 +27,14 @@ package net.fabricmc.loom.test.integration
import com.google.common.hash.HashCode
import com.google.common.hash.Hashing
import com.google.common.io.Files
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import spock.util.environment.RestoreSystemProperties
import static net.fabricmc.loom.test.LoomTestConstants.*
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static java.lang.System.setProperty
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class ReproducibleBuildTest extends Specification implements GradleProjectTestTrait {
@@ -41,21 +42,27 @@ class ReproducibleBuildTest extends Specification implements GradleProjectTestTr
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "reproducible", version: version)
def gradle = gradleProject(project: "reproducible", version: version)
when:
setProperty('loom.test.reproducible', 'true')
def result = gradle.run(task: "build")
setProperty('loom.test.reproducible', 'true')
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
generateMD5(gradle.getOutputFile("fabric-example-mod-1.0.0.jar")) == modHash
generateMD5(gradle.getOutputFile("fabric-example-mod-1.0.0-sources.jar")) in sourceHash // Done for different line endings.
result.task(":build").outcome == SUCCESS
generateMD5(gradle.getOutputFile("fabric-example-mod-1.0.0.jar")) == modHash
generateMD5(gradle.getOutputFile("fabric-example-mod-1.0.0-sources.jar")) in sourceHash // Done for different line endings.
where:
version | modHash | sourceHash
DEFAULT_GRADLE | "ed3306ef60f434c55048cba8de5dab95" | ["0d9eec9248d93eb6ec4a1cd4d927e609", "436bf54ef015576b0a338d55d9a0bb82"]
PRE_RELEASE_GRADLE | "ed3306ef60f434c55048cba8de5dab95" | ["0d9eec9248d93eb6ec4a1cd4d927e609", "436bf54ef015576b0a338d55d9a0bb82"]
version | modHash | sourceHash
DEFAULT_GRADLE | "ed3306ef60f434c55048cba8de5dab95" | [
"0d9eec9248d93eb6ec4a1cd4d927e609",
"436bf54ef015576b0a338d55d9a0bb82"
]
PRE_RELEASE_GRADLE | "ed3306ef60f434c55048cba8de5dab95" | [
"0d9eec9248d93eb6ec4a1cd4d927e609",
"436bf54ef015576b0a338d55d9a0bb82"
]
}
String generateMD5(File file) {

View File

@@ -24,11 +24,12 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import spock.util.environment.RestoreSystemProperties
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -37,34 +38,34 @@ class RunConfigTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "Run config #task"() {
setup:
def gradle = gradleProject(project: "runconfigs", sharedFiles: true)
def gradle = gradleProject(project: "runconfigs", sharedFiles: true)
when:
def result = gradle.run(task: task)
def result = gradle.run(task: task)
then:
result.task(":${task}").outcome == SUCCESS
result.output.contains("This contains a space")
result.task(":${task}").outcome == SUCCESS
result.output.contains("This contains a space")
where:
task | _
'runClient' | _
'runServer' | _
'runTestmodClient' | _
'runTestmodServer' | _
'runAutoTestServer' | _
task | _
'runClient' | _
'runServer' | _
'runTestmodClient' | _
'runTestmodServer' | _
'runAutoTestServer' | _
}
@RestoreSystemProperties
@Unroll
def "idea auto configuration (gradle #version)"() {
setup:
System.setProperty("idea.sync.active", "true")
def gradle = gradleProject(project: "minimalBase", version: version)
System.setProperty("idea.sync.active", "true")
def gradle = gradleProject(project: "minimalBase", version: version)
new File(gradle.projectDir, ".idea").mkdirs()
new File(gradle.projectDir, ".idea").mkdirs()
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18.1"
mappings "net.fabricmc:yarn:1.18.1+build.18:v2"
@@ -73,13 +74,13 @@ class RunConfigTest extends Specification implements GradleProjectTestTrait {
'''
when:
// Dont run with any tasks, the idea sync task should be invoked automatically due to the system prop
def result = gradle.run(tasks: [])
// Dont run with any tasks, the idea sync task should be invoked automatically due to the system prop
def result = gradle.run(tasks: [])
then:
result.task(":ideaSyncTask").outcome == SUCCESS
result.task(":ideaSyncTask").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,10 +24,11 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -36,9 +37,9 @@ class SignatureFixesTest extends Specification implements GradleProjectTestTrait
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << '''
gradle.buildGradle << '''
dependencies {
minecraft "com.mojang:minecraft:1.18-pre1"
mappings "net.fabricmc:yarn:1.18-pre1+build.14:v2"
@@ -46,12 +47,12 @@ class SignatureFixesTest extends Specification implements GradleProjectTestTrait
'''
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,15 +24,16 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.MockMavenServerTrait
import spock.lang.Specification
import spock.lang.Stepwise
import spock.lang.Unroll
import spock.util.environment.RestoreSystemProperties
import static net.fabricmc.loom.test.LoomTestConstants.*
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.MockMavenServerTrait
import static java.lang.System.setProperty
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
/**
@@ -44,17 +45,17 @@ class SignedProjectTest extends Specification implements MockMavenServerTrait, G
@RestoreSystemProperties
def "sign and publish lib #version"() {
setup:
setProperty('loom.test.secretKey', PRIVATE_KEY)
def gradle = gradleProject(project: "signed", version: version)
setProperty('loom.test.secretKey', PRIVATE_KEY)
def gradle = gradleProject(project: "signed", version: version)
when:
def result = gradle.run(task: "publish")
then:
result.task(":publish").outcome == SUCCESS
result.task(":publish").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
static final String PRIVATE_KEY = """

View File

@@ -24,53 +24,54 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.ServerRunner
import java.util.concurrent.TimeUnit
import spock.lang.Specification
import spock.lang.Timeout
import spock.lang.Unroll
import java.util.concurrent.TimeUnit
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.test.util.ServerRunner
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@Timeout(value = 20, unit = TimeUnit.MINUTES)
class SimpleProjectTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build and run (gradle #version)"() {
setup:
def gradle = gradleProject(project: "simple", version: version)
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()
def server = ServerRunner.create(gradle.projectDir, "1.16.5")
.withMod(gradle.getOutputFile("fabric-example-mod-1.0.0.jar"))
.withFabricApi()
when:
def result = gradle.run(task: "build")
def serverResult = server.run()
def result = gradle.run(task: "build")
def serverResult = server.run()
then:
result.task(":build").outcome == SUCCESS
gradle.getOutputZipEntry("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-sources.jar", "net/fabricmc/example/mixin/ExampleMixin.java").contains("class_442") // Very basic test to ensure sources got remapped
result.task(":build").outcome == SUCCESS
gradle.getOutputZipEntry("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-sources.jar", "net/fabricmc/example/mixin/ExampleMixin.java").contains("class_442") // Very basic test to ensure sources got remapped
serverResult.successful()
serverResult.output.contains("Hello simple Fabric mod") // A check to ensure our mod init was actually called
serverResult.successful()
serverResult.output.contains("Hello simple Fabric mod") // A check to ensure our mod init was actually called
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "#ide config generation"() {
setup:
def gradle = gradleProject(project: "simple", sharedFiles: true)
def gradle = gradleProject(project: "simple", sharedFiles: true)
when:
def result = gradle.run(task: ide)
def result = gradle.run(task: ide)
then:
result.task(":${ide}").outcome == SUCCESS
result.task(":${ide}").outcome == SUCCESS
where:
ide | _
'idea' | _
'eclipse' | _
'vscode' | _
ide | _
'idea' | _
'eclipse' | _
'vscode' | _
}
}

View File

@@ -24,26 +24,27 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
class SplitProjectTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "splitSources", version: version)
@Unroll
def "build (gradle #version)"() {
setup:
def gradle = gradleProject(project: "splitSources", version: version)
when:
def result = gradle.run(tasks: ["build", "generateDLIConfig"])
when:
def result = gradle.run(tasks: ["build", "generateDLIConfig"])
then:
result.task(":build").outcome == SUCCESS
then:
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
}
where:
version << STANDARD_TEST_VERSIONS
}
}

View File

@@ -24,11 +24,12 @@
package net.fabricmc.loom.test.integration
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import java.nio.charset.StandardCharsets
import spock.lang.Specification
import java.nio.charset.StandardCharsets
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import net.fabricmc.loom.util.ZipUtils
import static net.fabricmc.loom.test.LoomTestConstants.*
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
@@ -38,29 +39,29 @@ class UnpickTest extends Specification implements GradleProjectTestTrait {
def "unpick decompile"() {
setup:
def gradle = gradleProject(project: "unpick", version: version)
def gradle = gradleProject(project: "unpick", version: version)
when:
def result = gradle.run(task: "genSources")
def result = gradle.run(task: "genSources")
then:
result.task(":genSources").outcome == SUCCESS
getClassSource(gradle, "net/minecraft/block/CakeBlock.java").contains("Block.DEFAULT_SET_BLOCK_STATE_FLAG")
result.task(":genSources").outcome == SUCCESS
getClassSource(gradle, "net/minecraft/block/CakeBlock.java").contains("Block.DEFAULT_SET_BLOCK_STATE_FLAG")
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
def "unpick build"() {
setup:
def gradle = gradleProject(project: "unpick", version: version)
def gradle = gradleProject(project: "unpick", version: version)
when:
def result = gradle.run(task: "build")
def result = gradle.run(task: "build")
then:
result.task(":build").outcome == SUCCESS
result.task(":build").outcome == SUCCESS
where:
version << STANDARD_TEST_VERSIONS
version << STANDARD_TEST_VERSIONS
}
private static String getClassSource(GradleProject gradle, String classname, String mappings = MAPPINGS) {

View File

@@ -24,14 +24,14 @@
package net.fabricmc.loom.test.integration.buildSrc.decompile
import java.nio.file.Path
import net.fabricmc.loom.api.decompilers.DecompilationMetadata
import net.fabricmc.loom.api.decompilers.LoomDecompiler
import java.nio.file.Path
class CustomDecompiler implements LoomDecompiler {
@Override
void decompile(Path compiledJar, Path sourcesDestination, Path linemapDestination, DecompilationMetadata metaData) {
println("Running custom decompiler")
}
@Override
void decompile(Path compiledJar, Path sourcesDestination, Path linemapDestination, DecompilationMetadata metaData) {
println("Running custom decompiler")
}
}

View File

@@ -30,12 +30,12 @@ import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
abstract class PreDecompileTask extends DefaultTask {
@OutputFile
abstract RegularFileProperty getOutputFile()
@OutputFile
abstract RegularFileProperty getOutputFile()
@TaskAction
def run() {
println("Writing test file")
getOutputFile().asFile.get().text = "Test"
}
@TaskAction
def run() {
println("Writing test file")
getOutputFile().asFile.get().text = "Test"
}
}

View File

@@ -24,26 +24,27 @@
package net.fabricmc.loom.test.integration.buildSrc.decompile
import net.fabricmc.loom.LoomGradleExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import net.fabricmc.loom.LoomGradleExtension
class TestPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println("Test plugin")
def extension = LoomGradleExtension.get(project)
@Override
void apply(Project project) {
println("Test plugin")
def extension = LoomGradleExtension.get(project)
def preDecompileTask = project.tasks.register("preDecompile", PreDecompileTask.class) {
outputFile = project.file("output.txt")
}
def preDecompileTask = project.tasks.register("preDecompile", PreDecompileTask.class) {
outputFile = project.file("output.txt")
}
extension.decompilerOptions.register("custom") {
decompilerClassName.set(CustomDecompiler.class.name)
extension.decompilerOptions.register("custom") {
decompilerClassName.set(CustomDecompiler.class.name)
// BuiltBy shouldn't be required, but for some reason it is? Any ideas?
classpath.from(preDecompileTask)
classpath.builtBy(preDecompileTask)
}
}
// BuiltBy shouldn't be required, but for some reason it is? Any ideas?
classpath.from(preDecompileTask)
classpath.builtBy(preDecompileTask)
}
}
}

View File

@@ -24,11 +24,12 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.configuration.mods.ArtifactMetadata
import net.fabricmc.loom.configuration.mods.ArtifactRef
import java.nio.file.Path
import spock.lang.Specification
import java.nio.file.Path
import net.fabricmc.loom.configuration.mods.ArtifactMetadata
import net.fabricmc.loom.configuration.mods.ArtifactRef
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.RemapRequirements.*
import static net.fabricmc.loom.test.util.ZipTestUtils.*
@@ -36,68 +37,68 @@ import static net.fabricmc.loom.test.util.ZipTestUtils.*
class ArtifactMetadataTest extends Specification {
def "is fabric mod"() {
given:
def zip = createZip(entries)
def zip = createZip(entries)
when:
def metadata = createMetadata(zip)
def metadata = createMetadata(zip)
then:
isMod == metadata.isFabricMod()
isMod == metadata.isFabricMod()
where:
isMod | entries
false | ["hello.json": "{}"] // None Mod jar
true | ["fabric.mod.json": "{}"] // Fabric mod
isMod | entries
false | ["hello.json": "{}"] // None Mod jar
true | ["fabric.mod.json": "{}"] // Fabric mod
}
def "remap requirements"() {
given:
def zip = createZip(entries)
def zip = createZip(entries)
when:
def metadata = createMetadata(zip)
def metadata = createMetadata(zip)
then:
requirements == metadata.remapRequirements()
requirements == metadata.remapRequirements()
where:
requirements | entries
DEFAULT | ["fabric.mod.json": "{}"] // Default
OPT_OUT | ["META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // opt-out
OPT_IN | ["META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // opt-in
requirements | entries
DEFAULT | ["fabric.mod.json": "{}"] // Default
OPT_OUT | ["META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // opt-out
OPT_IN | ["META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // opt-in
}
def "Should Remap" () {
given:
def zip = createZip(entries)
def zip = createZip(entries)
when:
def metadata = createMetadata(zip)
def result = metadata.shouldRemap()
def metadata = createMetadata(zip)
def result = metadata.shouldRemap()
then:
result == shouldRemap
result == shouldRemap
where:
shouldRemap | entries
false | ["hello.json": "{}"] // None Mod jar
true | ["fabric.mod.json": "{}"] // Fabric mod
false | ["fabric.mod.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // Fabric mod opt-out
true | ["fabric.mod.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // Fabric mod opt-in
false | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // None opt-out
true | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // None opt-int
false | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "broken")]// Invalid format
false | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Something", "Hello")] // Invalid format
shouldRemap | entries
false | ["hello.json": "{}"] // None Mod jar
true | ["fabric.mod.json": "{}"] // Fabric mod
false | ["fabric.mod.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // Fabric mod opt-out
true | ["fabric.mod.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // Fabric mod opt-in
false | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // None opt-out
true | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // None opt-int
false | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "broken")]// Invalid format
false | ["hello.json": "{}",
"META-INF/MANIFEST.MF": manifest("Something", "Hello")] // Invalid format
}
def "Installer data"() {
given:
def zip = createZip(entries)
def zip = createZip(entries)
when:
def metadata = createMetadata(zip)
def metadata = createMetadata(zip)
then:
isLoader == (metadata.installerData() != null)
isLoader == (metadata.installerData() != null)
where:
isLoader | entries
true | ["fabric.mod.json": "{}", "fabric-installer.json": "{}"] // Fabric mod, with installer data
false | ["fabric.mod.json": "{}"] // Fabric mod, no installer data
isLoader | entries
true | ["fabric.mod.json": "{}", "fabric-installer.json": "{}"] // Fabric mod, with installer data
false | ["fabric.mod.json": "{}"] // Fabric mod, no installer data
}
private static ArtifactMetadata createMetadata(Path zip) {

View File

@@ -24,26 +24,27 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.util.Checksum
import org.gradle.api.Project
import spock.lang.Specification
import net.fabricmc.loom.util.Checksum
class ChecksumTest extends Specification {
def "project hash"() {
given:
def project = Mock(Project)
project.getPath() >> path
project.getProjectDir() >> new File(dir)
def project = Mock(Project)
project.getPath() >> path
project.getProjectDir() >> new File(dir)
when:
def hash = Checksum.projectHash(project)
def hash = Checksum.projectHash(project)
then:
!hash.empty
!hash.empty
where:
path | dir
":" | "C://mod"
":sub" | "/Users/test/Documents/modding/fabric-loom"
path | dir
":" | "C://mod"
":sub" | "/Users/test/Documents/modding/fabric-loom"
}
}

View File

@@ -25,50 +25,51 @@
package net.fabricmc.loom.test.unit
import groovy.xml.QName
import net.fabricmc.loom.util.GroovyXmlUtil
import spock.lang.Specification
import net.fabricmc.loom.util.GroovyXmlUtil
class GroovyXmlUtilTest extends Specification {
def "getOrCreateNode finds existing node"() {
when:
def xmlTree = new XmlParser().parseText(text)
def existingNode = xmlTree[innerName]
def actualNode = GroovyXmlUtil.getOrCreateNode(xmlTree, innerName)
def "getOrCreateNode finds existing node"() {
when:
def xmlTree = new XmlParser().parseText(text)
def existingNode = xmlTree[innerName]
def actualNode = GroovyXmlUtil.getOrCreateNode(xmlTree, innerName)
then:
existingNode.text() == actualNode.text()
then:
existingNode.text() == actualNode.text()
where:
innerName | text
"bar" | "<foo><bar>inner content to ensure correct</bar></foo>"
"dependencies" | "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"><dependencies>inner content to ensure correct</dependencies></project>"
}
where:
innerName | text
"bar" | "<foo><bar>inner content to ensure correct</bar></foo>"
"dependencies" | "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"><dependencies>inner content to ensure correct</dependencies></project>"
}
def "getOrCreateNode creates a node if needed"() {
when:
def xmlTree = new XmlParser().parseText(text)
def actualNode = GroovyXmlUtil.getOrCreateNode(xmlTree, innerName)
def "getOrCreateNode creates a node if needed"() {
when:
def xmlTree = new XmlParser().parseText(text)
def actualNode = GroovyXmlUtil.getOrCreateNode(xmlTree, innerName)
then:
xmlTree[QName.valueOf(actualNode.name().toString())] != null
then:
xmlTree[QName.valueOf(actualNode.name().toString())] != null
where:
innerName | text
"bar" | "<foo></foo>"
"dependencies" | "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"></project>"
}
where:
innerName | text
"bar" | "<foo></foo>"
"dependencies" | "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"></project>"
}
def "getNode finds existing node"() {
when:
def xmlTree = new XmlParser().parseText(text)
def actualNode = GroovyXmlUtil.getNode(xmlTree, innerName)
def "getNode finds existing node"() {
when:
def xmlTree = new XmlParser().parseText(text)
def actualNode = GroovyXmlUtil.getNode(xmlTree, innerName)
then:
actualNode.isPresent()
then:
actualNode.isPresent()
where:
innerName | text
"bar" | "<foo><bar>inner content to ensure correct</bar></foo>"
"dependencies" | "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"><dependencies>inner content to ensure correct</dependencies></project>"
}
where:
innerName | text
"bar" | "<foo><bar>inner content to ensure correct</bar></foo>"
"dependencies" | "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"><dependencies>inner content to ensure correct</dependencies></project>"
}
}

View File

@@ -24,42 +24,43 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.util.ipc.IPCClient
import net.fabricmc.loom.util.ipc.IPCServer
import spock.lang.Specification
import spock.lang.Timeout
import java.nio.file.Files
import java.util.function.Consumer
import spock.lang.Specification
import spock.lang.Timeout
import net.fabricmc.loom.util.ipc.IPCClient
import net.fabricmc.loom.util.ipc.IPCServer
@Timeout(20)
class IPCTest extends Specification {
def "ipc test"() {
given:
def path = Files.createTempFile("loom", "ipc")
Files.deleteIfExists(path)
def "ipc test"() {
given:
def path = Files.createTempFile("loom", "ipc")
Files.deleteIfExists(path)
def received = []
Consumer<String> consumer = { str ->
println str
received << str
}
def received = []
Consumer<String> consumer = { str ->
println str
received << str
}
when:
def ipcServer = new IPCServer(path, consumer)
when:
def ipcServer = new IPCServer(path, consumer)
new IPCClient(path).withCloseable { client ->
client.accept("Test")
client.accept("Hello")
}
new IPCClient(path).withCloseable { client ->
client.accept("Test")
client.accept("Hello")
}
// Allow ipcServer to finish reading, before closing.
while (received.size() != 2) { }
ipcServer.close()
// Allow ipcServer to finish reading, before closing.
while (received.size() != 2) { }
ipcServer.close()
then:
received.size() == 2
received[0] == "Test"
received[1] == "Hello"
}
then:
received.size() == 2
received[0] == "Test"
received[1] == "Hello"
}
}

View File

@@ -24,53 +24,57 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.configuration.ide.RunConfig
import net.fabricmc.loom.configuration.ide.idea.IdeaSyncTask
import java.nio.charset.StandardCharsets
import org.intellij.lang.annotations.Language
import spock.lang.Specification
import java.nio.charset.StandardCharsets
import net.fabricmc.loom.configuration.ide.RunConfig
import net.fabricmc.loom.configuration.ide.idea.IdeaSyncTask
class IdeaClasspathModificationsTest extends Specification {
def "configure exclusions"() {
when:
def input = fromDummy()
def output = IdeaSyncTask.setClasspathModificationsInXml(input, ["/path/to/file.jar"])
def "configure exclusions"() {
when:
def input = fromDummy()
def output = IdeaSyncTask.setClasspathModificationsInXml(input, ["/path/to/file.jar"])
then:
output == EXPECTED
}
then:
output == EXPECTED
}
def "re-configure exclusions"() {
when:
def input = fromDummy()
def output = IdeaSyncTask.setClasspathModificationsInXml(input, ["/path/to/file.jar"])
output = IdeaSyncTask.setClasspathModificationsInXml(output, ["/path/to/file.jar", "/path/to/another.jar"])
def "re-configure exclusions"() {
when:
def input = fromDummy()
def output = IdeaSyncTask.setClasspathModificationsInXml(input, ["/path/to/file.jar"])
output = IdeaSyncTask.setClasspathModificationsInXml(output, [
"/path/to/file.jar",
"/path/to/another.jar"
])
then:
output == EXPECTED2
}
then:
output == EXPECTED2
}
private String fromDummy() {
String dummyConfig
private String fromDummy() {
String dummyConfig
IdeaSyncTask.class.getClassLoader().getResourceAsStream("idea_run_config_template.xml").withCloseable {
dummyConfig = new String(it.readAllBytes(), StandardCharsets.UTF_8)
}
IdeaSyncTask.class.getClassLoader().getResourceAsStream("idea_run_config_template.xml").withCloseable {
dummyConfig = new String(it.readAllBytes(), StandardCharsets.UTF_8)
}
dummyConfig = dummyConfig.replace("%NAME%", "Minecraft Client")
dummyConfig = dummyConfig.replace("%MAIN_CLASS%", "net.minecraft.client.Main")
dummyConfig = dummyConfig.replace("%IDEA_MODULE%", "main.test")
dummyConfig = dummyConfig.replace("%RUN_DIRECTORY%", ".run")
dummyConfig = dummyConfig.replace("%PROGRAM_ARGS%", RunConfig.joinArguments([]).replaceAll("\"", "&quot;"))
dummyConfig = dummyConfig.replace("%VM_ARGS%", RunConfig.joinArguments([]).replaceAll("\"", "&quot;"))
dummyConfig = dummyConfig.replace("%NAME%", "Minecraft Client")
dummyConfig = dummyConfig.replace("%MAIN_CLASS%", "net.minecraft.client.Main")
dummyConfig = dummyConfig.replace("%IDEA_MODULE%", "main.test")
dummyConfig = dummyConfig.replace("%RUN_DIRECTORY%", ".run")
dummyConfig = dummyConfig.replace("%PROGRAM_ARGS%", RunConfig.joinArguments([]).replaceAll("\"", "&quot;"))
dummyConfig = dummyConfig.replace("%VM_ARGS%", RunConfig.joinArguments([]).replaceAll("\"", "&quot;"))
return dummyConfig
}
return dummyConfig
}
@Language("XML")
private static final String EXPECTED = '''
@Language("XML")
private static final String EXPECTED = '''
<component name="ProjectRunConfigurationManager">
<configuration default="false" factoryName="Application" name="Minecraft Client" type="Application">
<option name="MAIN_CLASS_NAME" value="net.minecraft.client.Main"/>
@@ -89,8 +93,8 @@ class IdeaClasspathModificationsTest extends Specification {
</component>
'''.trim()
@Language("XML")
private static final String EXPECTED2 = '''
@Language("XML")
private static final String EXPECTED2 = '''
<component name="ProjectRunConfigurationManager">
<configuration default="false" factoryName="Application" name="Minecraft Client" type="Application">
<option name="MAIN_CLASS_NAME" value="net.minecraft.client.Main"/>
@@ -108,5 +112,4 @@ class IdeaClasspathModificationsTest extends Specification {
<classpathModifications><entry exclude="true" path="/path/to/file.jar"/><entry exclude="true" path="/path/to/another.jar"/></classpathModifications></configuration>
</component>
'''.trim()
}

View File

@@ -24,9 +24,10 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.configuration.mods.JarSplitter
import spock.lang.Specification
import net.fabricmc.loom.configuration.mods.JarSplitter
class JarSplitterTest extends Specification {
public static final String SPLIT_INPUT_JAR_URL = "https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-lifecycle-events-v1/2.1.0%2B33fbc738a9/fabric-lifecycle-events-v1-2.1.0%2B33fbc738a9.jar"
public static final String CLIENT_INPUT_JAR_URL = "https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-renderer-indigo/0.6.10%2B5187d39f95/fabric-renderer-indigo-0.6.10%2B5187d39f95.jar"
@@ -37,53 +38,53 @@ class JarSplitterTest extends Specification {
def "analyse: split"() {
given:
def inputJar = downloadJarIfNotExists(SPLIT_INPUT_JAR_URL, "split.jar")
def inputJar = downloadJarIfNotExists(SPLIT_INPUT_JAR_URL, "split.jar")
when:
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
then:
target == JarSplitter.Target.SPLIT
target == JarSplitter.Target.SPLIT
}
def "analyse: client"() {
given:
def inputJar = downloadJarIfNotExists(CLIENT_INPUT_JAR_URL, "client.jar")
def inputJar = downloadJarIfNotExists(CLIENT_INPUT_JAR_URL, "client.jar")
when:
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
then:
target == JarSplitter.Target.CLIENT_ONLY
target == JarSplitter.Target.CLIENT_ONLY
}
def "analyse: common"() {
given:
def inputJar = downloadJarIfNotExists(COMMON_INPUT_JAR_URL, "common.jar")
def inputJar = downloadJarIfNotExists(COMMON_INPUT_JAR_URL, "common.jar")
when:
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
then:
target == JarSplitter.Target.COMMON_ONLY
target == JarSplitter.Target.COMMON_ONLY
}
def "analyse: normal"() {
given:
def inputJar = downloadJarIfNotExists(NORMAL_INPUT_JAR_URL, "normal.jar")
def inputJar = downloadJarIfNotExists(NORMAL_INPUT_JAR_URL, "normal.jar")
when:
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
def target = new JarSplitter(inputJar.toPath()).analyseTarget()
then:
target == null
target == null
}
def "split jar"() {
given:
def inputJar = downloadJarIfNotExists(SPLIT_INPUT_JAR_URL, "split.jar")
def commonOutputJar = getFile("common-out.jar")
def clientOutputJar = getFile("client-out.jar")
def inputJar = downloadJarIfNotExists(SPLIT_INPUT_JAR_URL, "split.jar")
def commonOutputJar = getFile("common-out.jar")
def clientOutputJar = getFile("client-out.jar")
def jarSplitter = new JarSplitter(inputJar.toPath())
def jarSplitter = new JarSplitter(inputJar.toPath())
when:
jarSplitter.split(commonOutputJar.toPath(), clientOutputJar.toPath())
jarSplitter.split(commonOutputJar.toPath(), clientOutputJar.toPath())
then:
commonOutputJar.exists()
clientOutputJar.exists()
commonOutputJar.exists()
clientOutputJar.exists()
}
File downloadJarIfNotExists(String url, String name) {

View File

@@ -24,27 +24,27 @@
package net.fabricmc.loom.test.unit
import java.util.function.Function
import net.fabricmc.loom.configuration.providers.mappings.IntermediaryMappingsProvider
import net.fabricmc.loom.test.util.GradleTestUtil
import net.fabricmc.loom.util.download.Download
import java.util.function.Function
import static org.mockito.Mockito.spy
import static org.mockito.Mockito.when
class LoomMocks {
static IntermediaryMappingsProvider intermediaryMappingsProviderMock(String minecraftVersion, String intermediaryUrl) {
def minecraftVersionProperty = GradleTestUtil.mockProperty(minecraftVersion)
def intermediaryUrlProperty = GradleTestUtil.mockProperty(intermediaryUrl)
def downloaderProperty = GradleTestUtil.mockProperty(Download.&create as Function)
static IntermediaryMappingsProvider intermediaryMappingsProviderMock(String minecraftVersion, String intermediaryUrl) {
def minecraftVersionProperty = GradleTestUtil.mockProperty(minecraftVersion)
def intermediaryUrlProperty = GradleTestUtil.mockProperty(intermediaryUrl)
def downloaderProperty = GradleTestUtil.mockProperty(Download.&create as Function)
Objects.requireNonNull(minecraftVersionProperty.get())
Objects.requireNonNull(minecraftVersionProperty.get())
def mock = spy(IntermediaryMappingsProvider.class)
when(mock.getMinecraftVersion()).thenReturn(minecraftVersionProperty)
when(mock.getIntermediaryUrl()).thenReturn(intermediaryUrlProperty)
when(mock.getDownloader()).thenReturn(downloaderProperty)
return mock
}
def mock = spy(IntermediaryMappingsProvider.class)
when(mock.getMinecraftVersion()).thenReturn(minecraftVersionProperty)
when(mock.getIntermediaryUrl()).thenReturn(intermediaryUrlProperty)
when(mock.getDownloader()).thenReturn(downloaderProperty)
return mock
}
}

View File

@@ -24,47 +24,48 @@
package net.fabricmc.loom.test.unit
import spock.lang.Specification
import net.fabricmc.loom.configuration.providers.BundleMetadata
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarSplitter
import net.fabricmc.loom.test.util.GradleTestUtil
import spock.lang.Specification
class MinecraftJarSplitterTest extends Specification {
public static final String CLIENT_JAR_URL = "https://launcher.mojang.com/v1/objects/7e46fb47609401970e2818989fa584fd467cd036/client.jar"
public static final String SERVER_BUNDLE_JAR_URL = "https://launcher.mojang.com/v1/objects/125e5adf40c659fd3bce3e66e67a16bb49ecc1b9/server.jar"
public static final String CLIENT_JAR_URL = "https://launcher.mojang.com/v1/objects/7e46fb47609401970e2818989fa584fd467cd036/client.jar"
public static final String SERVER_BUNDLE_JAR_URL = "https://launcher.mojang.com/v1/objects/125e5adf40c659fd3bce3e66e67a16bb49ecc1b9/server.jar"
public static final File mcJarDir = File.createTempDir()
public static final File mcJarDir = File.createTempDir()
def "split jars"() {
given:
def clientJar = downloadJarIfNotExists(CLIENT_JAR_URL, "client.jar")
def serverBundleJar = downloadJarIfNotExists(SERVER_BUNDLE_JAR_URL, "server_bundle.jar")
def serverJar = new File(mcJarDir, "server.jar")
def "split jars"() {
given:
def clientJar = downloadJarIfNotExists(CLIENT_JAR_URL, "client.jar")
def serverBundleJar = downloadJarIfNotExists(SERVER_BUNDLE_JAR_URL, "server_bundle.jar")
def serverJar = new File(mcJarDir, "server.jar")
def clientOnlyJar = new File(mcJarDir, "client_only.jar")
def commonJar = new File(mcJarDir, "common.jar")
when:
def serverBundleMetadata = BundleMetadata.fromJar(serverBundleJar.toPath())
serverBundleMetadata.versions().find().unpackEntry(serverBundleJar.toPath(), serverJar.toPath(), GradleTestUtil.mockProject())
def clientOnlyJar = new File(mcJarDir, "client_only.jar")
def commonJar = new File(mcJarDir, "common.jar")
when:
def serverBundleMetadata = BundleMetadata.fromJar(serverBundleJar.toPath())
serverBundleMetadata.versions().find().unpackEntry(serverBundleJar.toPath(), serverJar.toPath(), GradleTestUtil.mockProject())
clientOnlyJar.delete()
commonJar.delete()
clientOnlyJar.delete()
commonJar.delete()
new MinecraftJarSplitter(clientJar.toPath(), serverJar.toPath()).withCloseable {
it.split(clientOnlyJar.toPath(), commonJar.toPath())
}
then:
serverBundleMetadata.versions().size() == 1
}
new MinecraftJarSplitter(clientJar.toPath(), serverJar.toPath()).withCloseable {
it.split(clientOnlyJar.toPath(), commonJar.toPath())
}
then:
serverBundleMetadata.versions().size() == 1
}
File downloadJarIfNotExists(String url, String name) {
File dst = new File(mcJarDir, name)
File downloadJarIfNotExists(String url, String name) {
File dst = new File(mcJarDir, name)
if (!dst.exists()) {
dst.parentFile.mkdirs()
dst << new URL(url).newInputStream()
}
if (!dst.exists()) {
dst.parentFile.mkdirs()
dst << new URL(url).newInputStream()
}
return dst
}
return dst
}
}

View File

@@ -24,30 +24,31 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.api.RemapConfigurationSettings
import net.fabricmc.loom.configuration.RemapConfigurations
import net.fabricmc.loom.test.util.GradleTestUtil
import org.gradle.api.tasks.SourceSet
import spock.lang.Specification
import net.fabricmc.loom.api.RemapConfigurationSettings
import net.fabricmc.loom.configuration.RemapConfigurations
import net.fabricmc.loom.test.util.GradleTestUtil
class RemapConfigurationsTest extends Specification {
private static final RemapConfigurations.ConfigurationOption IMPLEMENTATION_OPTION = new RemapConfigurations.ConfigurationOption(SourceSet::getImplementationConfigurationName, true, true, RemapConfigurationSettings.PublishingMode.RUNTIME_ONLY)
private static final RemapConfigurations.ConfigurationOption IMPLEMENTATION_OPTION = new RemapConfigurations.ConfigurationOption(SourceSet.&getImplementationConfigurationName, true, true, RemapConfigurationSettings.PublishingMode.RUNTIME_ONLY)
def "testmod impl name"() {
given:
def sourceSet = GradleTestUtil.mockSourceSet("testmod")
def sourceSet = GradleTestUtil.mockSourceSet("testmod")
when:
def name = IMPLEMENTATION_OPTION.name(sourceSet)
def name = IMPLEMENTATION_OPTION.name(sourceSet)
then:
name == "modTestmodImplementation"
name == "modTestmodImplementation"
}
def "main impl name"() {
given:
def sourceSet = GradleTestUtil.mockSourceSet("main")
def sourceSet = GradleTestUtil.mockSourceSet("main")
when:
def name = IMPLEMENTATION_OPTION.name(sourceSet)
def name = IMPLEMENTATION_OPTION.name(sourceSet)
then:
name == "modImplementation"
name == "modImplementation"
}
}

View File

@@ -24,15 +24,19 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.configuration.ide.RunConfig
import spock.lang.Specification
class RunConfigUnitTest extends Specification {
def "escape arguments"() {
when:
def args = RunConfig.joinArguments(["-Dfabric.test=123", "-Dfabric.test=abc 123"])
import net.fabricmc.loom.configuration.ide.RunConfig
then:
args == '-Dfabric.test=123 "-Dfabric.test=abc 123"'
}
class RunConfigUnitTest extends Specification {
def "escape arguments"() {
when:
def args = RunConfig.joinArguments([
"-Dfabric.test=123",
"-Dfabric.test=abc 123"
])
then:
args == '-Dfabric.test=123 "-Dfabric.test=abc 123"'
}
}

View File

@@ -24,8 +24,6 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.util.gradle.SourceSetHelper
import net.fabricmc.loom.util.gradle.SourceSetReference
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.intellij.lang.annotations.Language
@@ -33,93 +31,96 @@ import spock.lang.Shared
import spock.lang.Specification
import spock.util.environment.RestoreSystemProperties
import net.fabricmc.loom.util.gradle.SourceSetHelper
import net.fabricmc.loom.util.gradle.SourceSetReference
class SourceSetHelperTest extends Specification {
@Shared
private static File projectDir = File.createTempDir()
@Shared
private static File projectDir = File.createTempDir()
@RestoreSystemProperties
def "idea classpath"() {
given:
def miscXml = new File(projectDir, ".idea/misc.xml")
miscXml.parentFile.mkdirs()
miscXml.text = MISC_XML
@RestoreSystemProperties
def "idea classpath"() {
given:
def miscXml = new File(projectDir, ".idea/misc.xml")
miscXml.parentFile.mkdirs()
miscXml.text = MISC_XML
def mockProject = Mock(Project)
def mockSourceSet = Mock(SourceSet)
def mockProject = Mock(Project)
def mockSourceSet = Mock(SourceSet)
mockProject.getName() >> "UnitTest"
mockProject.getRootDir() >> projectDir
mockSourceSet.getName() >> "main"
mockProject.getName() >> "UnitTest"
mockProject.getRootDir() >> projectDir
mockSourceSet.getName() >> "main"
System.setProperty("fabric-loom.unit.testing", "true")
System.setProperty("fabric-loom.unit.testing", "true")
def ref = new SourceSetReference(mockSourceSet, mockProject)
when:
def result = SourceSetHelper.getIdeaClasspath(ref, mockProject)
def ref = new SourceSetReference(mockSourceSet, mockProject)
when:
def result = SourceSetHelper.getIdeaClasspath(ref, mockProject)
then:
result.size() == 1
!result[0].toString().startsWith("file:")
then:
result.size() == 1
!result[0].toString().startsWith("file:")
println(result[0].toString())
}
println(result[0].toString())
}
@RestoreSystemProperties
def "eclipse classpath"() {
given:
def classpath = new File(projectDir, ".classpath")
classpath.createNewFile()
@RestoreSystemProperties
def "eclipse classpath"() {
given:
def classpath = new File(projectDir, ".classpath")
classpath.createNewFile()
def binDir = new File(projectDir, "bin")
binDir.mkdirs()
def binDir = new File(projectDir, "bin")
binDir.mkdirs()
def mockProject = Mock(Project)
def mockSourceSet = Mock(SourceSet)
def mockProject = Mock(Project)
def mockSourceSet = Mock(SourceSet)
mockProject.getName() >> "UnitTest"
mockProject.getProjectDir() >> projectDir
mockSourceSet.getName() >> "main"
mockProject.getName() >> "UnitTest"
mockProject.getProjectDir() >> projectDir
mockSourceSet.getName() >> "main"
System.setProperty("fabric-loom.unit.testing", "true")
System.setProperty("fabric-loom.unit.testing", "true")
def ref = new SourceSetReference(mockSourceSet, mockProject)
when:
def result = SourceSetHelper.getEclipseClasspath(ref, mockProject)
def ref = new SourceSetReference(mockSourceSet, mockProject)
when:
def result = SourceSetHelper.getEclipseClasspath(ref, mockProject)
then:
result.size() == 1
println(result[0].toString())
}
then:
result.size() == 1
println(result[0].toString())
}
@RestoreSystemProperties
def "vscode classpath"() {
given:
def dotVscode = new File(projectDir, ".vscode")
dotVscode.mkdirs()
@RestoreSystemProperties
def "vscode classpath"() {
given:
def dotVscode = new File(projectDir, ".vscode")
dotVscode.mkdirs()
def binDir = new File(projectDir, "bin")
binDir.mkdirs()
def binDir = new File(projectDir, "bin")
binDir.mkdirs()
def mockProject = Mock(Project)
def mockSourceSet = Mock(SourceSet)
def mockProject = Mock(Project)
def mockSourceSet = Mock(SourceSet)
mockProject.getName() >> "UnitTest"
mockProject.getProjectDir() >> projectDir
mockSourceSet.getName() >> "main"
mockProject.getName() >> "UnitTest"
mockProject.getProjectDir() >> projectDir
mockSourceSet.getName() >> "main"
System.setProperty("fabric-loom.unit.testing", "true")
System.setProperty("fabric-loom.unit.testing", "true")
def ref = new SourceSetReference(mockSourceSet, mockProject)
when:
def result = SourceSetHelper.getVscodeClasspath(ref, mockProject)
def ref = new SourceSetReference(mockSourceSet, mockProject)
when:
def result = SourceSetHelper.getVscodeClasspath(ref, mockProject)
then:
result.size() == 1
println(result[0].toString())
}
then:
result.size() == 1
println(result[0].toString())
}
@Language("xml")
private static String MISC_XML = """<?xml version="1.0" encoding="UTF-8"?>
@Language("xml")
private static String MISC_XML = """<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">

View File

@@ -24,24 +24,25 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.util.Strings
import spock.lang.Specification
import spock.lang.Unroll
class StringsTest extends Specification {
@Unroll
def "capitalize '#input'"() {
when:
def result = Strings.capitalize(input)
then:
result == expected
import net.fabricmc.loom.util.Strings
where:
input | expected
'' | ''
' \n ' | ' \n '
'world' | 'World'
'helloWorld' | 'HelloWorld'
'\u00E4mp\u00E4ri' | '\u00C4mp\u00E4ri'
}
class StringsTest extends Specification {
@Unroll
def "capitalize '#input'"() {
when:
def result = Strings.capitalize(input)
then:
result == expected
where:
input | expected
'' | ''
' \n ' | ' \n '
'world' | 'World'
'helloWorld' | 'HelloWorld'
'\u00E4mp\u00E4ri' | '\u00C4mp\u00E4ri'
}
}

View File

@@ -24,47 +24,48 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.task.ValidateMixinNameTask
import org.spongepowered.asm.mixin.Mixin
import org.spongepowered.asm.mixin.gen.Accessor
import spock.lang.Specification
import net.fabricmc.loom.task.ValidateMixinNameTask
class ValidateMixinNameTest extends Specification {
def "TestMixin"() {
when:
def mixin = getMixin(TestMixin.class)
def mixin = getMixin(TestMixin.class)
then:
mixin.className() == "net/fabricmc/loom/test/unit/TestMixin"
mixin.target().internalName == "net/fabricmc/loom/test/unit/Test"
mixin.expectedClassName() == "TestMixin"
!mixin.accessor()
mixin.className() == "net/fabricmc/loom/test/unit/TestMixin"
mixin.target().internalName == "net/fabricmc/loom/test/unit/Test"
mixin.expectedClassName() == "TestMixin"
!mixin.accessor()
}
def "TestInnerMixin"() {
when:
def mixin = getMixin(TestInnerMixin.class)
def mixin = getMixin(TestInnerMixin.class)
then:
mixin.className() == "net/fabricmc/loom/test/unit/TestInnerMixin"
mixin.target().internalName == "net/fabricmc/loom/test/unit/Test\$Inner"
mixin.expectedClassName() == "TestInnerMixin"
!mixin.accessor()
mixin.className() == "net/fabricmc/loom/test/unit/TestInnerMixin"
mixin.target().internalName == "net/fabricmc/loom/test/unit/Test\$Inner"
mixin.expectedClassName() == "TestInnerMixin"
!mixin.accessor()
}
def "TestAccessor"() {
when:
def mixin = getMixin(TestAccessor.class)
def mixin = getMixin(TestAccessor.class)
then:
mixin.className() == "net/fabricmc/loom/test/unit/TestAccessor"
mixin.target().internalName == "net/fabricmc/loom/test/unit/Test"
mixin.expectedClassName() == "TestAccessor"
mixin.accessor()
mixin.className() == "net/fabricmc/loom/test/unit/TestAccessor"
mixin.target().internalName == "net/fabricmc/loom/test/unit/Test"
mixin.expectedClassName() == "TestAccessor"
mixin.accessor()
}
def "TestManyTargetsMixin"() {
when:
def mixin = getMixin(TestManyTargetsMixin.class)
def mixin = getMixin(TestManyTargetsMixin.class)
then:
mixin == null
mixin == null
}
static ValidateMixinNameTask.Mixin getMixin(Class<?> clazz) {

View File

@@ -24,129 +24,130 @@
package net.fabricmc.loom.test.unit
import net.fabricmc.loom.util.Pair
import net.fabricmc.loom.util.ZipUtils
import spock.lang.Specification
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import spock.lang.Specification
import net.fabricmc.loom.util.Pair
import net.fabricmc.loom.util.ZipUtils
class ZipUtilsTest extends Specification {
def "pack"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This is a test of packing"
def "pack"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This is a test of packing"
when:
ZipUtils.pack(dir.toPath(), zip)
when:
ZipUtils.pack(dir.toPath(), zip)
then:
Files.exists(zip)
ZipUtils.contains(zip, "test.txt")
!ZipUtils.contains(zip, "nope.txt")
new String( ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "This is a test of packing"
}
then:
Files.exists(zip)
ZipUtils.contains(zip, "test.txt")
!ZipUtils.contains(zip, "nope.txt")
new String( ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "This is a test of packing"
}
def "transform string"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This is a test of transforming"
def "transform string"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This is a test of transforming"
when:
ZipUtils.pack(dir.toPath(), zip)
def transformed = ZipUtils.transformString(zip, [
new Pair<String, ZipUtils.UnsafeUnaryOperator<String>>("test.txt", new ZipUtils.UnsafeUnaryOperator<String>() {
@Override
String apply(String arg) throws IOException {
return arg.toUpperCase()
}
})
])
when:
ZipUtils.pack(dir.toPath(), zip)
def transformed = ZipUtils.transformString(zip, [
new Pair<String, ZipUtils.UnsafeUnaryOperator<String>>("test.txt", new ZipUtils.UnsafeUnaryOperator<String>() {
@Override
String apply(String arg) throws IOException {
return arg.toUpperCase()
}
})
])
then:
transformed == 1
ZipUtils.contains(zip, "test.txt")
new String( ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "THIS IS A TEST OF TRANSFORMING"
}
then:
transformed == 1
ZipUtils.contains(zip, "test.txt")
new String( ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "THIS IS A TEST OF TRANSFORMING"
}
def "replace string"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This has not been replaced"
def "replace string"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This has not been replaced"
when:
ZipUtils.pack(dir.toPath(), zip)
ZipUtils.replace(zip, "test.txt", "This has been replaced".bytes)
when:
ZipUtils.pack(dir.toPath(), zip)
ZipUtils.replace(zip, "test.txt", "This has been replaced".bytes)
then:
ZipUtils.contains(zip, "test.txt")
new String(ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "This has been replaced"
}
then:
ZipUtils.contains(zip, "test.txt")
new String(ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "This has been replaced"
}
def "add file"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This is original"
def "add file"() {
given:
def dir = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(dir, "test.txt").text = "This is original"
when:
ZipUtils.pack(dir.toPath(), zip)
ZipUtils.add(zip, "test2.txt", "This has been added".bytes)
when:
ZipUtils.pack(dir.toPath(), zip)
ZipUtils.add(zip, "test2.txt", "This has been added".bytes)
then:
ZipUtils.contains(zip, "test.txt")
ZipUtils.contains(zip, "test2.txt")
new String(ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "This is original"
new String(ZipUtils.unpack(zip, "test2.txt"), StandardCharsets.UTF_8) == "This has been added"
}
then:
ZipUtils.contains(zip, "test.txt")
ZipUtils.contains(zip, "test2.txt")
new String(ZipUtils.unpack(zip, "test.txt"), StandardCharsets.UTF_8) == "This is original"
new String(ZipUtils.unpack(zip, "test2.txt"), StandardCharsets.UTF_8) == "This has been added"
}
def "unpack all"() {
given:
def input = File.createTempDir()
def output = File.createTempDir()
def "unpack all"() {
given:
def input = File.createTempDir()
def output = File.createTempDir()
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(input, "test.txt").text = "This is a test of unpacking all"
def zip = File.createTempFile("loom-zip-test", ".zip").toPath()
new File(input, "test.txt").text = "This is a test of unpacking all"
def outputFile = new File(output, "test.txt")
def outputFile = new File(output, "test.txt")
when:
ZipUtils.pack(input.toPath(), zip)
ZipUtils.unpackAll(zip, output.toPath())
when:
ZipUtils.pack(input.toPath(), zip)
ZipUtils.unpackAll(zip, output.toPath())
then:
outputFile.exists()
outputFile.text == "This is a test of unpacking all"
}
then:
outputFile.exists()
outputFile.text == "This is a test of unpacking all"
}
def "is zip"() {
setup:
// Create zip
def dir = Files.createTempDirectory("loom-zip-test")
def zip = Files.createTempFile("loom-zip-test", ".zip")
def fileInside = dir.resolve("text.txt")
Files.writeString(fileInside, "hello world")
ZipUtils.pack(dir, zip)
def "is zip"() {
setup:
// Create zip
def dir = Files.createTempDirectory("loom-zip-test")
def zip = Files.createTempFile("loom-zip-test", ".zip")
def fileInside = dir.resolve("text.txt")
Files.writeString(fileInside, "hello world")
ZipUtils.pack(dir, zip)
when:
def result = ZipUtils.isZip(zip)
when:
def result = ZipUtils.isZip(zip)
then:
result
}
then:
result
}
def "is not zip"() {
setup:
def textFile = Files.createTempFile("loom-zip-test", ".txt")
Files.writeString(textFile, "hello world")
def "is not zip"() {
setup:
def textFile = Files.createTempFile("loom-zip-test", ".txt")
Files.writeString(textFile, "hello world")
when:
def result = ZipUtils.isZip(textFile)
when:
def result = ZipUtils.isZip(textFile)
then:
!result
}
then:
!result
}
}

View File

@@ -24,209 +24,210 @@
package net.fabricmc.loom.test.unit.download
import io.javalin.http.HttpStatus
import net.fabricmc.loom.util.Checksum
import net.fabricmc.loom.util.download.Download
import net.fabricmc.loom.util.download.DownloadException
import net.fabricmc.loom.util.download.DownloadExecutor
import net.fabricmc.loom.util.download.DownloadProgressListener
import spock.lang.IgnoreIf
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.attribute.FileTime
import java.time.Duration
import java.time.Instant
import io.javalin.http.HttpStatus
import spock.lang.IgnoreIf
import net.fabricmc.loom.util.Checksum
import net.fabricmc.loom.util.download.Download
import net.fabricmc.loom.util.download.DownloadException
import net.fabricmc.loom.util.download.DownloadExecutor
import net.fabricmc.loom.util.download.DownloadProgressListener
class DownloadFileTest extends DownloadTest {
@IgnoreIf({ os.windows }) // Requires admin on windows.
def "Directory: Symlink"() {
setup:
server.get("/symlinkFile") {
it.result("Hello World")
}
def output = new File(File.createTempDir(), "file.txt").toPath()
def linkedtmp = new File(File.createTempDir(), "linkedtmp").toPath()
Files.createSymbolicLink(linkedtmp, output.getParent())
def symlink = Paths.get(linkedtmp.toString(), "file.txt")
server.get("/symlinkFile") {
it.result("Hello World")
}
def output = new File(File.createTempDir(), "file.txt").toPath()
def linkedtmp = new File(File.createTempDir(), "linkedtmp").toPath()
Files.createSymbolicLink(linkedtmp, output.getParent())
def symlink = Paths.get(linkedtmp.toString(), "file.txt")
when:
def result = Download.create("$PATH/symlinkFile").downloadPath(symlink)
def result = Download.create("$PATH/symlinkFile").downloadPath(symlink)
then:
Files.readString(symlink) == "Hello World"
Files.readString(symlink) == "Hello World"
}
def "File: Simple"() {
setup:
server.get("/simpleFile") {
it.result("Hello World")
}
server.get("/simpleFile") {
it.result("Hello World")
}
def output = new File(File.createTempDir(), "subdir/file.txt").toPath()
def output = new File(File.createTempDir(), "subdir/file.txt").toPath()
when:
def result = Download.create("$PATH/simpleFile").downloadPath(output)
def result = Download.create("$PATH/simpleFile").downloadPath(output)
then:
Files.readString(output) == "Hello World"
Files.readString(output) == "Hello World"
}
def "File: Not found"() {
setup:
server.get("/fileNotfound") {
it.status(404)
}
server.get("/fileNotfound") {
it.status(404)
}
def output = new File(File.createTempDir(), "file.txt").toPath()
def output = new File(File.createTempDir(), "file.txt").toPath()
when:
def result = Download.create("$PATH/stringNotFound").downloadPath(output)
def result = Download.create("$PATH/stringNotFound").downloadPath(output)
then:
thrown DownloadException
thrown DownloadException
}
def "Cache: Sha1"() {
setup:
int requestCount = 0
int requestCount = 0
server.get("/sha1.txt") {
it.result("Hello World")
requestCount ++
}
server.get("/sha1.txt") {
it.result("Hello World")
requestCount ++
}
def output = new File(File.createTempDir(), "file.txt").toPath()
def output = new File(File.createTempDir(), "file.txt").toPath()
when:
for (i in 0..<2) {
Download.create("$PATH/sha1.txt")
for (i in 0..<2) {
Download.create("$PATH/sha1.txt")
.sha1("0a4d55a8d778e5022fab701977c5d840bbc486d0")
.downloadPath(output)
}
}
then:
requestCount == 1
requestCount == 1
}
def "Invalid Sha1"() {
setup:
server.get("/sha1.invalid") {
it.result("Hello World")
}
server.get("/sha1.invalid") {
it.result("Hello World")
}
def output = new File(File.createTempDir(), "file.txt").toPath()
def output = new File(File.createTempDir(), "file.txt").toPath()
when:
Download.create("$PATH/sha1.invalid")
Download.create("$PATH/sha1.invalid")
.sha1("d139cccf047a749691416ce385d3f168c1e28309")
.downloadPath(output)
then:
// Ensure the file we downloaded with the wrong hash was deleted
Files.notExists(output)
thrown DownloadException
// Ensure the file we downloaded with the wrong hash was deleted
Files.notExists(output)
thrown DownloadException
}
def "Offline"() {
setup:
int requestCount = 0
int requestCount = 0
server.get("/offline.txt") {
it.result("Hello World")
requestCount ++
}
server.get("/offline.txt") {
it.result("Hello World")
requestCount ++
}
def output = new File(File.createTempDir(), "offline.txt").toPath()
def output = new File(File.createTempDir(), "offline.txt").toPath()
when:
Download.create("$PATH/offline.txt")
Download.create("$PATH/offline.txt")
.downloadPath(output)
Download.create("$PATH/offline.txt")
Download.create("$PATH/offline.txt")
.offline()
.downloadPath(output)
then:
requestCount == 1
requestCount == 1
}
def "Max Age"() {
setup:
int requestCount = 0
int requestCount = 0
server.get("/maxage.txt") {
it.result("Hello World")
requestCount ++
}
server.get("/maxage.txt") {
it.result("Hello World")
requestCount ++
}
def output = new File(File.createTempDir(), "maxage.txt").toPath()
def output = new File(File.createTempDir(), "maxage.txt").toPath()
when:
Download.create("$PATH/maxage.txt")
Download.create("$PATH/maxage.txt")
.maxAge(Duration.ofDays(1))
.downloadPath(output)
Download.create("$PATH/maxage.txt")
Download.create("$PATH/maxage.txt")
.maxAge(Duration.ofDays(1))
.downloadPath(output)
def twoDaysAgo = Instant.now() - Duration.ofDays(2)
Files.setLastModifiedTime(output, FileTime.from(twoDaysAgo))
def twoDaysAgo = Instant.now() - Duration.ofDays(2)
Files.setLastModifiedTime(output, FileTime.from(twoDaysAgo))
Download.create("$PATH/maxage.txt")
Download.create("$PATH/maxage.txt")
.maxAge(Duration.ofDays(1))
.downloadPath(output)
then:
requestCount == 2
requestCount == 2
}
def "ETag"() {
setup:
int requestCount = 0
int requestCount = 0
server.get("/etag") {
def clientEtag = it.req.getHeader("If-None-Match")
server.get("/etag") {
def clientEtag = it.req.getHeader("If-None-Match")
def result = "Hello world"
def etag = result.hashCode().toString()
it.header("ETag", etag)
def result = "Hello world"
def etag = result.hashCode().toString()
it.header("ETag", etag)
if (clientEtag == etag) {
// Etag matches, no need to send the data.
it.status(HttpStatus.NOT_MODIFIED)
return
}
it.result(result)
requestCount ++
if (clientEtag == etag) {
// Etag matches, no need to send the data.
it.status(HttpStatus.NOT_MODIFIED)
return
}
it.result(result)
requestCount ++
}
def output = new File(File.createTempDir(), "etag.txt").toPath()
when:
for (i in 0..<3) {
Download.create("$PATH/etag")
for (i in 0..<3) {
Download.create("$PATH/etag")
.etag(true)
.downloadPath(output)
}
}
then:
requestCount == 1
requestCount == 1
}
def "Progress: File"() {
setup:
server.get("/progressFile") {
it.result("Hello World")
}
server.get("/progressFile") {
it.result("Hello World")
}
def output = new File(File.createTempDir(), "file.txt").toPath()
def started, ended = false
def output = new File(File.createTempDir(), "file.txt").toPath()
def started, ended = false
when:
Download.create("$PATH/progressFile")
Download.create("$PATH/progressFile")
.progress(new DownloadProgressListener() {
@Override
void onStart() {
@@ -245,20 +246,20 @@ class DownloadFileTest extends DownloadTest {
.downloadPath(output)
then:
started
ended
started
ended
}
def "Progress: String"() {
setup:
server.get("/progressString") {
it.result("Hello World")
}
server.get("/progressString") {
it.result("Hello World")
}
def started, ended = false
def started, ended = false
when:
Download.create("$PATH/progressFile")
Download.create("$PATH/progressFile")
.progress(new DownloadProgressListener() {
@Override
void onStart() {
@@ -277,90 +278,90 @@ class DownloadFileTest extends DownloadTest {
.downloadString()
then:
started
ended
started
ended
}
def "File: Async"() {
setup:
server.get("/async1") {
it.result("Hello World")
}
server.get("/async1") {
it.result("Hello World")
}
def dir = File.createTempDir().toPath()
def dir = File.createTempDir().toPath()
when:
new DownloadExecutor(2).withCloseable {
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("1.txt"), it)
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("2.txt"), it)
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("3.txt"), it)
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("4.txt"), it)
}
new DownloadExecutor(2).withCloseable {
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("1.txt"), it)
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("2.txt"), it)
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("3.txt"), it)
Download.create("$PATH/async1").downloadPathAsync(dir.resolve("4.txt"), it)
}
then:
Files.readString(dir.resolve("4.txt")) == "Hello World"
Files.readString(dir.resolve("4.txt")) == "Hello World"
}
def "File: Async Error"() {
setup:
server.get("/async2") {
it.result("Hello World")
}
server.get("/async2") {
it.result("Hello World")
}
def dir = File.createTempDir().toPath()
def dir = File.createTempDir().toPath()
when:
new DownloadExecutor(2).withCloseable {
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("1.txt"), it)
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("2.txt"), it)
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("3.txt"), it)
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("4.txt"), it)
new DownloadExecutor(2).withCloseable {
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("1.txt"), it)
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("2.txt"), it)
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("3.txt"), it)
Download.create("$PATH/async2").downloadPathAsync(dir.resolve("4.txt"), it)
Download.create("$PATH/asyncError").downloadPathAsync(dir.resolve("5.txt"), it)
Download.create("$PATH/asyncError2").downloadPathAsync(dir.resolve("6.txt"), it)
}
Download.create("$PATH/asyncError").downloadPathAsync(dir.resolve("5.txt"), it)
Download.create("$PATH/asyncError2").downloadPathAsync(dir.resolve("6.txt"), it)
}
then:
thrown DownloadException
thrown DownloadException
}
def "File: Large"() {
setup:
byte[] data = new byte[1024 * 1024 * 10] // 10MB
new Random().nextBytes(data)
byte[] data = new byte[1024 * 1024 * 10] // 10MB
new Random().nextBytes(data)
server.get("/largeFile") {
it.result(data)
}
server.get("/largeFile") {
it.result(data)
}
def output = new File(File.createTempDir(), "file").toPath()
def output = new File(File.createTempDir(), "file").toPath()
when:
def result = Download.create("$PATH/largeFile").downloadPath(output)
def result = Download.create("$PATH/largeFile").downloadPath(output)
then:
Files.readAllBytes(output) == data
Files.readAllBytes(output) == data
}
def "File: Insecure protocol"() {
setup:
def output = new File(File.createTempDir(), "file").toPath()
def output = new File(File.createTempDir(), "file").toPath()
when:
def result = Download.create("http://fabricmc.net").downloadPath(output)
def result = Download.create("http://fabricmc.net").downloadPath(output)
then:
thrown IllegalArgumentException
thrown IllegalArgumentException
}
// Known
def "Download Mojang Mappings"() {
setup:
def file = File.createTempDir().toPath().resolve("client.txt")
def file = File.createTempDir().toPath().resolve("client.txt")
when:
Download.create("https://piston-data.mojang.com/v1/objects/8e8c9be5dc27802caba47053d4fdea328f7f89bd/client.txt")
.sha1("8e8c9be5dc27802caba47053d4fdea328f7f89bd")
.downloadPath(file)
Download.create("https://piston-data.mojang.com/v1/objects/8e8c9be5dc27802caba47053d4fdea328f7f89bd/client.txt")
.sha1("8e8c9be5dc27802caba47053d4fdea328f7f89bd")
.downloadPath(file)
then:
Checksum.sha1Hex(file) == "8e8c9be5dc27802caba47053d4fdea328f7f89bd"
Checksum.sha1Hex(file) == "8e8c9be5dc27802caba47053d4fdea328f7f89bd"
}
}

View File

@@ -25,95 +25,96 @@
package net.fabricmc.loom.test.unit.download
import io.javalin.http.HttpStatus
import net.fabricmc.loom.util.download.Download
import net.fabricmc.loom.util.download.DownloadException
class DownloadStringTest extends DownloadTest {
def "String: Download"() {
setup:
server.get("/downloadString") {
it.result("Hello World!")
}
server.get("/downloadString") {
it.result("Hello World!")
}
when:
def result = Download.create("$PATH/downloadString").downloadString()
def result = Download.create("$PATH/downloadString").downloadString()
then:
result == "Hello World!"
result == "Hello World!"
}
def "String: Not found"() {
setup:
server.get("/stringNotFound") {
it.status(404)
}
server.get("/stringNotFound") {
it.status(404)
}
when:
def result = Download.create("$PATH/stringNotFound")
def result = Download.create("$PATH/stringNotFound")
.maxRetries(3) // Ensure we still error as expected when retrying
.downloadString()
then:
thrown DownloadException
thrown DownloadException
}
def "String: Redirect"() {
setup:
server.get("/redirectString2") {
it.result("Hello World!")
}
server.get("/redirectString") {
it.redirect("$PATH/redirectString2")
}
server.get("/redirectString2") {
it.result("Hello World!")
}
server.get("/redirectString") {
it.redirect("$PATH/redirectString2")
}
when:
def result = Download.create("$PATH/redirectString").downloadString()
def result = Download.create("$PATH/redirectString").downloadString()
then:
result == "Hello World!"
result == "Hello World!"
}
def "String: Retries"() {
setup:
int requests = 0
server.get("/retryString") {
requests ++
int requests = 0
server.get("/retryString") {
requests ++
if (requests < 3) {
it.status(HttpStatus.INTERNAL_SERVER_ERROR)
return
}
it.result("Hello World " + requests)
if (requests < 3) {
it.status(HttpStatus.INTERNAL_SERVER_ERROR)
return
}
it.result("Hello World " + requests)
}
when:
def result = Download.create("$PATH/retryString")
def result = Download.create("$PATH/retryString")
.maxRetries(3)
.downloadString()
then:
result == "Hello World 3"
result == "Hello World 3"
}
def "String: File cache"() {
setup:
server.get("/downloadString2") {
it.result("Hello World!")
}
server.get("/downloadString2") {
it.result("Hello World!")
}
when:
def output = new File(File.createTempDir(), "file.txt").toPath()
def result = Download.create("$PATH/downloadString2").downloadString(output)
def output = new File(File.createTempDir(), "file.txt").toPath()
def result = Download.create("$PATH/downloadString2").downloadString(output)
then:
result == "Hello World!"
result == "Hello World!"
}
def "String: Insecure protocol"() {
when:
def result = Download.create("http://fabricmc.net").downloadString()
def result = Download.create("http://fabricmc.net").downloadString()
then:
thrown IllegalArgumentException
thrown IllegalArgumentException
}
}

View File

@@ -26,11 +26,12 @@ package net.fabricmc.loom.test.unit.fmj
import com.google.gson.Gson
import com.google.gson.JsonObject
import org.intellij.lang.annotations.Language
import spock.lang.Specification
import net.fabricmc.loom.util.Constants
import net.fabricmc.loom.util.fmj.FabricModJsonFactory
import net.fabricmc.loom.util.fmj.FabricModJsonSource
import org.intellij.lang.annotations.Language
import spock.lang.Specification
class FabricModJsonV0Test extends Specification {
// I think this is the old v0 format ¯\_(ツ)_/¯
@@ -56,58 +57,61 @@ class FabricModJsonV0Test extends Specification {
def "version"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.version == 0
fmj.version == 0
}
def "id"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.id == "example-mod-id"
fmj.id == "example-mod-id"
}
def "mixins"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.mixinConfigurations == ["mixins.client.json", "mixins.common.json"]
fmj.mixinConfigurations == [
"mixins.client.json",
"mixins.common.json"
]
}
// Not supported in this version
def "injected interfaces"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE)
then:
jsonObject == null
jsonObject == null
}
// Not supported in this version
def "class tweaker"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.getClassTweakers() == [:]
fmj.getClassTweakers() == [:]
}
def "hash code"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.hashCode() == 930565976
fmj.hashCode() == 930565976
}
}

View File

@@ -26,12 +26,13 @@ package net.fabricmc.loom.test.unit.fmj
import com.google.gson.Gson
import com.google.gson.JsonObject
import org.intellij.lang.annotations.Language
import spock.lang.Specification
import net.fabricmc.loom.util.Constants
import net.fabricmc.loom.util.fmj.FabricModJsonFactory
import net.fabricmc.loom.util.fmj.FabricModJsonSource
import net.fabricmc.loom.util.fmj.ModEnvironment
import org.intellij.lang.annotations.Language
import spock.lang.Specification
class FabricModJsonV1Test extends Specification {
@Language("json")
@@ -63,57 +64,60 @@ class FabricModJsonV1Test extends Specification {
def "version"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.version == 1
fmj.version == 1
}
def "id"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.id == "example-mod-id"
fmj.id == "example-mod-id"
}
def "mixins"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.mixinConfigurations == ["test.client.mixins.json", "test.mixins.json"]
fmj.mixinConfigurations == [
"test.client.mixins.json",
"test.mixins.json"
]
}
def "injected interfaces"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE)
then:
jsonObject instanceof JsonObject
jsonObject.has("net/minecraft/class_123")
jsonObject instanceof JsonObject
jsonObject.has("net/minecraft/class_123")
}
def "access widener"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.getClassTweakers() == ["modid.accesswidener": ModEnvironment.UNIVERSAL]
fmj.getClassTweakers() == ["modid.accesswidener": ModEnvironment.UNIVERSAL]
}
def "hash code"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.hashCode() == 930565977
fmj.hashCode() == 930565977
}
}

View File

@@ -26,12 +26,13 @@ package net.fabricmc.loom.test.unit.fmj
import com.google.gson.Gson
import com.google.gson.JsonObject
import org.intellij.lang.annotations.Language
import spock.lang.Specification
import net.fabricmc.loom.util.Constants
import net.fabricmc.loom.util.fmj.FabricModJsonFactory
import net.fabricmc.loom.util.fmj.FabricModJsonSource
import net.fabricmc.loom.util.fmj.ModEnvironment
import org.intellij.lang.annotations.Language
import spock.lang.Specification
class FabricModJsonV2Test extends Specification {
@Language("json")
@@ -77,61 +78,65 @@ class FabricModJsonV2Test extends Specification {
def "version"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.version == 2
fmj.version == 2
}
def "id"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.id == "example-mod-id"
fmj.id == "example-mod-id"
}
def "mixins"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
new ArrayList<>(fmj.mixinConfigurations).sort() == ["test.client.mixins.json", "test.server.mixins.json", "test.mixins.json"].sort()
new ArrayList<>(fmj.mixinConfigurations).sort() == [
"test.client.mixins.json",
"test.server.mixins.json",
"test.mixins.json"
].sort()
}
def "injected interfaces"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE)
then:
jsonObject instanceof JsonObject
jsonObject.has("net/minecraft/class_123")
jsonObject instanceof JsonObject
jsonObject.has("net/minecraft/class_123")
}
def "class tweakers"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.getClassTweakers() == [
"client.ct": ModEnvironment.CLIENT,
"server.ct": ModEnvironment.SERVER,
"universal.ct": ModEnvironment.UNIVERSAL
]
fmj.getClassTweakers() == [
"client.ct": ModEnvironment.CLIENT,
"server.ct": ModEnvironment.SERVER,
"universal.ct": ModEnvironment.UNIVERSAL
]
}
def "hash code"() {
given:
def mockSource = Mock(FabricModJsonSource)
def mockSource = Mock(FabricModJsonSource)
when:
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource)
then:
fmj.hashCode() == 930565978
fmj.hashCode() == 930565978
}
}

View File

@@ -24,78 +24,79 @@
package net.fabricmc.loom.test.unit.kotlin
import org.objectweb.asm.ClassReader
import org.objectweb.asm.tree.ClassNode
import spock.lang.Specification
import net.fabricmc.loom.util.kotlin.KotlinClasspath
import net.fabricmc.loom.util.kotlin.KotlinPluginUtils
import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader
import net.fabricmc.tinyremapper.api.TrClass
import net.fabricmc.tinyremapper.api.TrEnvironment
import net.fabricmc.tinyremapper.api.TrRemapper
import org.objectweb.asm.ClassReader
import org.objectweb.asm.tree.ClassNode
import spock.lang.Specification
class KotlinRemapperClassloaderTest extends Specification {
private static String KOTLIN_VERSION = "1.6.10"
private static String KOTLIN_METADATA_VERSION = KotlinPluginUtils.kotlinMetadataVersion
private static String KOTLIN_URL = "https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/${KOTLIN_VERSION}/kotlin-stdlib-${KOTLIN_VERSION}.jar"
private static String KOTLIN_METADATA_URL = "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-metadata-jvm/${KOTLIN_METADATA_VERSION}/kotlinx-metadata-jvm-${KOTLIN_METADATA_VERSION}.jar"
private static String KOTLIN_VERSION = "1.6.10"
private static String KOTLIN_METADATA_VERSION = KotlinPluginUtils.kotlinMetadataVersion
private static String KOTLIN_URL = "https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/${KOTLIN_VERSION}/kotlin-stdlib-${KOTLIN_VERSION}.jar"
private static String KOTLIN_METADATA_URL = "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-metadata-jvm/${KOTLIN_METADATA_VERSION}/kotlinx-metadata-jvm-${KOTLIN_METADATA_VERSION}.jar"
def "Test Kotlin Remapper Classloader"() {
given:
def classLoader = KotlinRemapperClassloader.create(new TestKotlinClasspath())
def mockTrClass = Mock(TrClass)
def mockEnv = Mock(TrEnvironment)
def mockRemapper = Mock(TrRemapper)
def "Test Kotlin Remapper Classloader"() {
given:
def classLoader = KotlinRemapperClassloader.create(new TestKotlinClasspath())
def mockTrClass = Mock(TrClass)
def mockEnv = Mock(TrEnvironment)
def mockRemapper = Mock(TrRemapper)
mockRemapper.map(_) >> { args -> args[0] }
mockRemapper.mapMethodDesc(_) >> { args -> args[0] }
mockRemapper.map(_) >> { args -> args[0] }
mockRemapper.mapMethodDesc(_) >> { args -> args[0] }
mockEnv.remapper >> mockRemapper
mockTrClass.environment >> mockEnv
mockEnv.remapper >> mockRemapper
mockTrClass.environment >> mockEnv
def classReader = new ClassReader(getClassBytes("TestExtensionKt"))
def classReader = new ClassReader(getClassBytes("TestExtensionKt"))
when:
def extension = classLoader.tinyRemapperExtension
def visitor = extension.insertApplyVisitor(mockTrClass, new ClassNode())
when:
def extension = classLoader.tinyRemapperExtension
def visitor = extension.insertApplyVisitor(mockTrClass, new ClassNode())
classReader.accept(visitor, 0)
classReader.accept(visitor, 0)
then:
extension != null
visitor != null
then:
extension != null
visitor != null
// Ensure that the visitor is using the kotlin version specified on the classpath.
visitor.runtimeKotlinVersion == KOTLIN_VERSION
}
// Ensure that the visitor is using the kotlin version specified on the classpath.
visitor.runtimeKotlinVersion == KOTLIN_VERSION
}
private class TestKotlinClasspath implements KotlinClasspath {
@Override
String version() {
return KOTLIN_VERSION
}
private class TestKotlinClasspath implements KotlinClasspath {
@Override
String version() {
return KOTLIN_VERSION
}
@Override
Set<URL> classpath() {
def kotlin = downloadFile(KOTLIN_URL, "kotlin-stdlib.jar")
def metadata = downloadFile(KOTLIN_METADATA_URL, "kotlin-metadata.jar")
@Override
Set<URL> classpath() {
def kotlin = downloadFile(KOTLIN_URL, "kotlin-stdlib.jar")
def metadata = downloadFile(KOTLIN_METADATA_URL, "kotlin-metadata.jar")
return Set.of(
kotlin.toURI().toURL(),
metadata.toURI().toURL()
)
}
}
return Set.of(
kotlin.toURI().toURL(),
metadata.toURI().toURL()
)
}
}
File tempDir = File.createTempDir()
File downloadFile(String url, String name) {
File dst = new File(tempDir, name)
dst.parentFile.mkdirs()
dst << new URL(url).newInputStream()
return dst
}
File tempDir = File.createTempDir()
File downloadFile(String url, String name) {
File dst = new File(tempDir, name)
dst.parentFile.mkdirs()
dst << new URL(url).newInputStream()
return dst
}
def getClassBytes(String name) {
return new File("src/test/resources/classes/${name}.class").bytes
}
def getClassBytes(String name) {
return new File("src/test/resources/classes/${name}.class").bytes
}
}

View File

@@ -24,73 +24,74 @@
package net.fabricmc.loom.test.unit.layeredmappings
import java.nio.file.Path
import java.util.function.Consumer
import spock.lang.Unroll
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace
import net.fabricmc.loom.api.mappings.layered.spec.FileSpec
import net.fabricmc.loom.configuration.providers.mappings.file.FileMappingsSpecBuilderImpl
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
import net.fabricmc.loom.util.ZipUtils
import net.fabricmc.loom.util.download.Download
import spock.lang.Unroll
import java.nio.file.Path
import java.util.function.Consumer
class FileMappingLayerTest extends LayeredMappingsSpecification {
@Unroll
def "read Yarn mappings from #setupType.displayName"() {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
setupType.setup.delegate = this
def mappingFile = setupType.setup.call()
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
setupType.setup.delegate = this
def mappingFile = setupType.setup.call()
when:
def builder = FileMappingsSpecBuilderImpl.builder(FileSpec.create(mappingFile))
setupType.mappingsSpec.accept(builder)
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
builder.build()
)
def builder = FileMappingsSpecBuilderImpl.builder(FileSpec.create(mappingFile))
setupType.mappingsSpec.accept(builder)
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
builder.build()
)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6111
mappings.classes[0].srcName == "net/minecraft/block/FenceBlock"
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].fields[0].srcName == "cullingShapes"
mappings.classes[0].fields[0].getDstName(0) == "field_11066"
mappings.classes[0].methods[0].srcName == "canConnectToFence"
mappings.classes[0].methods[0].getDstName(0) == "method_26375"
mappings.classes[0].methods[0].args[0].srcName == "state"
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6111
mappings.classes[0].srcName == "net/minecraft/block/FenceBlock"
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].fields[0].srcName == "cullingShapes"
mappings.classes[0].fields[0].getDstName(0) == "field_11066"
mappings.classes[0].methods[0].srcName == "canConnectToFence"
mappings.classes[0].methods[0].getDstName(0) == "method_26375"
mappings.classes[0].methods[0].args[0].srcName == "state"
where:
setupType << YarnSetupType.values()
setupType << YarnSetupType.values()
}
// Also tests the custom fallback namespace and source namespace functionality
def "read Mojang mappings from proguard"() {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
def mappingsDownload = VERSION_META_1_17.download('client_mappings')
def mappingsFile = new File(tempDir, 'mappings.txt')
Download.create(mappingsDownload.url())
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
def mappingsDownload = VERSION_META_1_17.download('client_mappings')
def mappingsFile = new File(tempDir, 'mappings.txt')
Download.create(mappingsDownload.url())
.downloadPath(mappingsFile.toPath())
when:
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
FileMappingsSpecBuilderImpl.builder(FileSpec.create(mappingsFile))
.fallbackNamespaces('named', 'official')
.mergeNamespace(MappingsNamespace.OFFICIAL)
.build()
)
def tiny = getTiny(mappings)
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
FileMappingsSpecBuilderImpl.builder(FileSpec.create(mappingsFile))
.fallbackNamespaces('named', 'official')
.mergeNamespace(MappingsNamespace.OFFICIAL)
.build()
)
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6113
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].methods[0].args.size() == 0 // No Args
tiny.contains('this$0')
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6113
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].methods[0].args.size() == 0 // No Args
tiny.contains('this$0')
}
enum YarnSetupType {

View File

@@ -27,17 +27,17 @@ package net.fabricmc.loom.test.unit.layeredmappings
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
class IntermediaryMappingLayerTest extends LayeredMappingsSpecification {
def "Read intermediary mappings" () {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
when:
def mappings = getSingleMapping(new IntermediaryMappingsSpec())
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "official"
mappings.dstNamespaces == ["intermediary", "named"]
mappings.classes.size() == 6107
mappings.getClass("abc").getDstName(0) == "net/minecraft/class_3191"
mappings.getClass("abc").getDstName(1) == "net/minecraft/class_3191"
}
def "Read intermediary mappings" () {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
when:
def mappings = getSingleMapping(new IntermediaryMappingsSpec())
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "official"
mappings.dstNamespaces == ["intermediary", "named"]
mappings.classes.size() == 6107
mappings.getClass("abc").getDstName(0) == "net/minecraft/class_3191"
mappings.getClass("abc").getDstName(1) == "net/minecraft/class_3191"
}
}

View File

@@ -24,106 +24,107 @@
package net.fabricmc.loom.test.unit.layeredmappings
import net.fabricmc.loom.configuration.providers.mappings.file.FileMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.utils.MavenFileSpec
import spock.lang.Specification
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl
import net.fabricmc.loom.configuration.providers.mappings.file.FileMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec
import net.fabricmc.loom.configuration.providers.mappings.utils.MavenFileSpec
import net.fabricmc.loom.util.ClosureAction
import spock.lang.Specification
class LayeredMappingSpecBuilderTest extends Specification {
def "simple mojmap" () {
when:
def spec = layered {
officialMojangMappings()
}
def layers = spec.layers()
then:
layers.size() == 2
spec.version == "layered+hash.2198"
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
}
def "simple mojmap" () {
when:
def spec = layered {
officialMojangMappings()
}
def layers = spec.layers()
then:
layers.size() == 2
spec.version == "layered+hash.2198"
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
}
def "simple mojmap with parchment" () {
when:
def dep = "I like cake"
def spec = layered() {
officialMojangMappings()
parchment(dep)
}
def layers = spec.layers()
def parchment = layers[2] as ParchmentMappingsSpec
then:
spec.version == "layered+hash.863752751"
layers.size() == 3
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
(parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I like cake"
parchment.removePrefix() == true
}
def "simple mojmap with parchment" () {
when:
def dep = "I like cake"
def spec = layered() {
officialMojangMappings()
parchment(dep)
}
def layers = spec.layers()
def parchment = layers[2] as ParchmentMappingsSpec
then:
spec.version == "layered+hash.863752751"
layers.size() == 3
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
(parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I like cake"
parchment.removePrefix() == true
}
def "simple mojmap with parchment keep prefix" () {
when:
def spec = layered() {
officialMojangMappings()
parchment("I like cake") {
it.removePrefix = false
}
}
def layers = spec.layers()
def parchment = layers[2] as ParchmentMappingsSpec
then:
spec.version == "layered+hash.863752757"
layers.size() == 3
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
(parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I like cake"
parchment.removePrefix() == false
}
def "simple mojmap with parchment keep prefix" () {
when:
def spec = layered() {
officialMojangMappings()
parchment("I like cake") {
it.removePrefix = false
}
}
def layers = spec.layers()
def parchment = layers[2] as ParchmentMappingsSpec
then:
spec.version == "layered+hash.863752757"
layers.size() == 3
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
(parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I like cake"
parchment.removePrefix() == false
}
def "simple mojmap with parchment keep prefix alternate hash" () {
when:
def spec = layered {
officialMojangMappings()
parchment("I really like cake") {
it.removePrefix = false
}
}
def layers = spec.layers()
def parchment = layers[2] as ParchmentMappingsSpec
then:
spec.version == "layered+hash.1144427140"
layers.size() == 3
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
(parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I really like cake"
parchment.removePrefix() == false
}
def "simple mojmap with parchment keep prefix alternate hash" () {
when:
def spec = layered {
officialMojangMappings()
parchment("I really like cake") {
it.removePrefix = false
}
}
def layers = spec.layers()
def parchment = layers[2] as ParchmentMappingsSpec
then:
spec.version == "layered+hash.1144427140"
layers.size() == 3
layers[0].class == IntermediaryMappingsSpec
layers[1].class == MojangMappingsSpec
layers[2].class == ParchmentMappingsSpec
(parchment.fileSpec() as MavenFileSpec).dependencyNotation() == "I really like cake"
parchment.removePrefix() == false
}
def "yarn through file mappings"() {
when:
def spec = layered {
mappings("net.fabricmc:yarn:1.18.1+build.1:v2")
}
def layers = spec.layers()
then:
spec.version == "layered+hash.1133958200"
layers.size() == 2
layers[0].class == IntermediaryMappingsSpec
layers[1].class == FileMappingsSpec
((layers[1] as FileMappingsSpec).fileSpec() as MavenFileSpec).dependencyNotation() == "net.fabricmc:yarn:1.18.1+build.1:v2"
}
def "yarn through file mappings"() {
when:
def spec = layered {
mappings("net.fabricmc:yarn:1.18.1+build.1:v2")
}
def layers = spec.layers()
then:
spec.version == "layered+hash.1133958200"
layers.size() == 2
layers[0].class == IntermediaryMappingsSpec
layers[1].class == FileMappingsSpec
((layers[1] as FileMappingsSpec).fileSpec() as MavenFileSpec).dependencyNotation() == "net.fabricmc:yarn:1.18.1+build.1:v2"
}
LayeredMappingSpec layered(@DelegatesTo(LayeredMappingSpecBuilderImpl) Closure cl) {
LayeredMappingSpecBuilderImpl builder = new LayeredMappingSpecBuilderImpl()
new ClosureAction(cl).execute(builder)
return builder.build()
}
LayeredMappingSpec layered(@DelegatesTo(LayeredMappingSpecBuilderImpl) Closure cl) {
LayeredMappingSpecBuilderImpl builder = new LayeredMappingSpecBuilderImpl()
new ClosureAction(cl).execute(builder)
return builder.build()
}
}

View File

@@ -24,6 +24,15 @@
package net.fabricmc.loom.test.unit.layeredmappings
import java.nio.file.Path
import java.util.function.Supplier
import java.util.zip.ZipFile
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.logging.Logger
import spock.lang.Specification
import net.fabricmc.loom.api.mappings.layered.MappingContext
import net.fabricmc.loom.api.mappings.layered.MappingLayer
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace
@@ -40,89 +49,81 @@ import net.fabricmc.mappingio.adapter.MappingDstNsReorder
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch
import net.fabricmc.mappingio.format.Tiny2Writer
import net.fabricmc.mappingio.tree.MemoryMappingTree
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.logging.Logger
import spock.lang.Specification
import java.nio.file.Path
import java.util.function.Supplier
import java.util.zip.ZipFile
abstract class LayeredMappingsSpecification extends Specification implements LayeredMappingsTestConstants {
Logger mockLogger = Mock(Logger)
MinecraftProvider mockMinecraftProvider = Mock(MinecraftProvider)
String intermediaryUrl
MappingContext mappingContext = new TestMappingContext()
Logger mockLogger = Mock(Logger)
MinecraftProvider mockMinecraftProvider = Mock(MinecraftProvider)
String intermediaryUrl
MappingContext mappingContext = new TestMappingContext()
File tempDir = File.createTempDir()
File tempDir = File.createTempDir()
Map<String, File> mavenFiles = [:]
Map<String, File> mavenFiles = [:]
def withMavenFile(String mavenNotation, File file) {
mavenFiles.put(mavenNotation, file)
}
def withMavenFile(String mavenNotation, File file) {
mavenFiles.put(mavenNotation, file)
}
File downloadFile(String url, String name) {
File dst = new File(tempDir, name)
dst.parentFile.mkdirs()
dst << new URL(url).newInputStream()
return dst
}
File downloadFile(String url, String name) {
File dst = new File(tempDir, name)
dst.parentFile.mkdirs()
dst << new URL(url).newInputStream()
return dst
}
File extractFileFromZip(File zipFile, String name) {
File dst = new File(tempDir, name)
dst.parentFile.mkdirs()
File extractFileFromZip(File zipFile, String name) {
File dst = new File(tempDir, name)
dst.parentFile.mkdirs()
new ZipFile(zipFile).withCloseable {
dst << it.getInputStream(it.getEntry(name))
}
return dst
}
new ZipFile(zipFile).withCloseable {
dst << it.getInputStream(it.getEntry(name))
}
return dst
}
MemoryMappingTree getSingleMapping(MappingsSpec<? extends MappingLayer> spec) {
MemoryMappingTree mappingTree = new MemoryMappingTree()
spec.createLayer(mappingContext).visit(mappingTree)
return mappingTree
}
MemoryMappingTree getSingleMapping(MappingsSpec<? extends MappingLayer> spec) {
MemoryMappingTree mappingTree = new MemoryMappingTree()
spec.createLayer(mappingContext).visit(mappingTree)
return mappingTree
}
MemoryMappingTree getLayeredMappings(MappingsSpec<? extends MappingLayer>... specs) {
LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList())
LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec)
return processor.getMappings(processor.resolveLayers(mappingContext))
}
MemoryMappingTree getLayeredMappings(MappingsSpec<? extends MappingLayer>... specs) {
LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList())
LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec)
return processor.getMappings(processor.resolveLayers(mappingContext))
}
UnpickLayer.UnpickData getUnpickData(MappingsSpec<? extends MappingLayer>... specs) {
LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList())
LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec)
return processor.getUnpickData(processor.resolveLayers(mappingContext))
}
UnpickLayer.UnpickData getUnpickData(MappingsSpec<? extends MappingLayer>... specs) {
LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList())
LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec)
return processor.getUnpickData(processor.resolveLayers(mappingContext))
}
String getTiny(MemoryMappingTree mappingTree) {
def sw = new StringWriter()
mappingTree.accept(new Tiny2Writer(sw, false))
return sw.toString()
}
String getTiny(MemoryMappingTree mappingTree) {
def sw = new StringWriter()
mappingTree.accept(new Tiny2Writer(sw, false))
return sw.toString()
}
MemoryMappingTree reorder(MemoryMappingTree mappingTree) {
def reorderedMappings = new MemoryMappingTree()
def nsReorder = new MappingDstNsReorder(reorderedMappings, Collections.singletonList(MappingsNamespace.NAMED.toString()))
def nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingsNamespace.INTERMEDIARY.toString(), true)
mappingTree.accept(nsSwitch)
return reorderedMappings
}
MemoryMappingTree reorder(MemoryMappingTree mappingTree) {
def reorderedMappings = new MemoryMappingTree()
def nsReorder = new MappingDstNsReorder(reorderedMappings, Collections.singletonList(MappingsNamespace.NAMED.toString()))
def nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingsNamespace.INTERMEDIARY.toString(), true)
mappingTree.accept(nsSwitch)
return reorderedMappings
}
def setup() {
mockMinecraftProvider.file(_) >> { args ->
return new File(tempDir, args[0])
}
}
def setup() {
mockMinecraftProvider.file(_) >> { args ->
return new File(tempDir, args[0])
}
}
class TestMappingContext implements MappingContext {
@Override
Path resolveDependency(Dependency dependency) {
throw new UnsupportedOperationException("TODO")
}
class TestMappingContext implements MappingContext {
@Override
Path resolveDependency(Dependency dependency) {
throw new UnsupportedOperationException("TODO")
}
@Override
Path resolveDependency(MinimalExternalModuleDependency dependency) {
@@ -130,32 +131,32 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
}
@Override
Path resolveMavenDependency(String mavenNotation) {
assert mavenFiles.containsKey(mavenNotation)
return mavenFiles.get(mavenNotation).toPath()
}
Path resolveMavenDependency(String mavenNotation) {
assert mavenFiles.containsKey(mavenNotation)
return mavenFiles.get(mavenNotation).toPath()
}
@Override
Supplier<MemoryMappingTree> intermediaryTree() {
return {
IntermediateMappingsService.create(LoomMocks.intermediaryMappingsProviderMock("test", intermediaryUrl), minecraftProvider()).memoryMappingTree
}
}
@Override
Supplier<MemoryMappingTree> intermediaryTree() {
return {
IntermediateMappingsService.create(LoomMocks.intermediaryMappingsProviderMock("test", intermediaryUrl), minecraftProvider()).memoryMappingTree
}
}
@Override
MinecraftProvider minecraftProvider() {
return mockMinecraftProvider
}
@Override
MinecraftProvider minecraftProvider() {
return mockMinecraftProvider
}
@Override
Path workingDirectory(String name) {
return new File(tempDir, name).toPath()
}
@Override
Path workingDirectory(String name) {
return new File(tempDir, name).toPath()
}
@Override
Logger getLogger() {
return mockLogger
}
@Override
Logger getLogger() {
return mockLogger
}
@Override
DownloadBuilder download(String url) {

View File

@@ -27,22 +27,22 @@ package net.fabricmc.loom.test.unit.layeredmappings
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta
interface LayeredMappingsTestConstants {
public static final String INTERMEDIARY_1_17_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.17/intermediary-1.17-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 String INTERMEDIARY_1_17_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.17/intermediary-1.17-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 = [
client_mappings: new MinecraftVersionMeta.Download(null, "227d16f520848747a59bef6f490ae19dc290a804", 6431705, "https://launcher.mojang.com/v1/objects/227d16f520848747a59bef6f490ae19dc290a804/client.txt"),
server_mappings: new MinecraftVersionMeta.Download(null, "84d80036e14bc5c7894a4fad9dd9f367d3000334", 4948536, "https://launcher.mojang.com/v1/objects/84d80036e14bc5c7894a4fad9dd9f367d3000334/server.txt")
]
public static final MinecraftVersionMeta VERSION_META_1_17 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_17, null, null, null, null, 0, null, null, null)
public static final Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_17 = [
client_mappings: new MinecraftVersionMeta.Download(null, "227d16f520848747a59bef6f490ae19dc290a804", 6431705, "https://launcher.mojang.com/v1/objects/227d16f520848747a59bef6f490ae19dc290a804/client.txt"),
server_mappings: new MinecraftVersionMeta.Download(null, "84d80036e14bc5c7894a4fad9dd9f367d3000334", 4948536, "https://launcher.mojang.com/v1/objects/84d80036e14bc5c7894a4fad9dd9f367d3000334/server.txt")
]
public static final MinecraftVersionMeta VERSION_META_1_17 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_17, null, null, null, null, 0, null, null, null)
public static final Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_16_5 = [
client_mappings: new MinecraftVersionMeta.Download(null, "e3dfb0001e1079a1af72ee21517330edf52e6192", 5746047, "https://launcher.mojang.com/v1/objects/e3dfb0001e1079a1af72ee21517330edf52e6192/client.txt"),
server_mappings: new MinecraftVersionMeta.Download(null, "81d5c793695d8cde63afddb40dde88e3a88132ac", 4400926, "https://launcher.mojang.com/v1/objects/81d5c793695d8cde63afddb40dde88e3a88132ac/server.txt")
]
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 Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_16_5 = [
client_mappings: new MinecraftVersionMeta.Download(null, "e3dfb0001e1079a1af72ee21517330edf52e6192", 5746047, "https://launcher.mojang.com/v1/objects/e3dfb0001e1079a1af72ee21517330edf52e6192/client.txt"),
server_mappings: new MinecraftVersionMeta.Download(null, "81d5c793695d8cde63afddb40dde88e3a88132ac", 4400926, "https://launcher.mojang.com/v1/objects/81d5c793695d8cde63afddb40dde88e3a88132ac/server.txt")
]
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 String PARCHMENT_NOTATION = "org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip"
public static final String PARCHMENT_URL = "https://maven.parchmentmc.net/org/parchmentmc/data/parchment-1.16.5/20210608-SNAPSHOT/parchment-1.16.5-20210608-SNAPSHOT.zip"
public static final String YARN_1_17_URL = "https://maven.fabricmc.net/net/fabricmc/yarn/1.17%2Bbuild.13/yarn-1.17%2Bbuild.13-v2.jar"
public static final String PARCHMENT_NOTATION = "org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip"
public static final String PARCHMENT_URL = "https://maven.parchmentmc.net/org/parchmentmc/data/parchment-1.16.5/20210608-SNAPSHOT/parchment-1.16.5-20210608-SNAPSHOT.zip"
public static final String YARN_1_17_URL = "https://maven.fabricmc.net/net/fabricmc/yarn/1.17%2Bbuild.13/yarn-1.17%2Bbuild.13-v2.jar"
}

View File

@@ -28,49 +28,49 @@ import net.fabricmc.loom.configuration.providers.mappings.intermediary.Intermedi
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpecBuilderImpl
class MojangMappingLayerTest extends LayeredMappingsSpecification {
def "Read mojang mappings with synthetic field names" () {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
when:
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
buildMojangMappingsSpec(true)
)
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6113
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].methods[0].args.size() == 0 // No Args
tiny.contains('this$0')
}
def "Read mojang mappings with synthetic field names" () {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
when:
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
buildMojangMappingsSpec(true)
)
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6113
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].methods[0].args.size() == 0 // No Args
tiny.contains('this$0')
}
def "Read mojang mappings without synthetic field names" () {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
when:
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
buildMojangMappingsSpec(false)
)
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6113
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].methods[0].args.size() == 0 // No Args
!tiny.contains('this$0')
}
def "Read mojang mappings without synthetic field names" () {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
when:
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
buildMojangMappingsSpec(false)
)
def tiny = getTiny(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 6113
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
mappings.classes[0].methods[0].args.size() == 0 // No Args
!tiny.contains('this$0')
}
static def buildMojangMappingsSpec(boolean nameSyntheticFields) {
def builder = MojangMappingsSpecBuilderImpl.builder()
builder.setNameSyntheticMembers(nameSyntheticFields)
return builder.build()
}
static def buildMojangMappingsSpec(boolean nameSyntheticFields) {
def builder = MojangMappingsSpecBuilderImpl.builder()
builder.setNameSyntheticMembers(nameSyntheticFields)
return builder.build()
}
}

View File

@@ -30,49 +30,49 @@ import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsS
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec
class ParchmentMappingLayerTest extends LayeredMappingsSpecification {
def "Read parchment mappings" () {
setup:
intermediaryUrl = INTERMEDIARY_1_16_5_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
when:
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
new MojangMappingsSpec(true),
new ParchmentMappingsSpec(FileSpec.create(PARCHMENT_NOTATION), false)
)
def tiny = getTiny(mappings)
def reorderedMappings = reorder(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 5747
mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2573"
mappings.classes[0].methods[0].args[0].srcName.hashCode() == -1008297992
reorderedMappings.getClass("net/minecraft/class_2573").getMethod("method_10913", "(Lnet/minecraft/class_1799;Lnet/minecraft/class_1767;)V").args.size() > 0
}
def "Read parchment mappings" () {
setup:
intermediaryUrl = INTERMEDIARY_1_16_5_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
when:
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
new MojangMappingsSpec(true),
new ParchmentMappingsSpec(FileSpec.create(PARCHMENT_NOTATION), false)
)
def tiny = getTiny(mappings)
def reorderedMappings = reorder(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 5747
mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2573"
mappings.classes[0].methods[0].args[0].srcName.hashCode() == -1008297992
reorderedMappings.getClass("net/minecraft/class_2573").getMethod("method_10913", "(Lnet/minecraft/class_1799;Lnet/minecraft/class_1767;)V").args.size() > 0
}
def "Read parchment mappings remove prefix" () {
setup:
intermediaryUrl = INTERMEDIARY_1_16_5_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
when:
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
new MojangMappingsSpec(true),
new ParchmentMappingsSpec(FileSpec.create(PARCHMENT_NOTATION), true)
)
def tiny = getTiny(mappings)
def reorderedMappings = reorder(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 5747
mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2573"
mappings.classes[0].methods[0].args[0].srcName.hashCode() == 109757064
reorderedMappings.getClass("net/minecraft/class_2573").getMethod("method_10913", "(Lnet/minecraft/class_1799;Lnet/minecraft/class_1767;)V").args.size() > 0
}
def "Read parchment mappings remove prefix" () {
setup:
intermediaryUrl = INTERMEDIARY_1_16_5_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
when:
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
def mappings = getLayeredMappings(
new IntermediaryMappingsSpec(),
new MojangMappingsSpec(true),
new ParchmentMappingsSpec(FileSpec.create(PARCHMENT_NOTATION), true)
)
def tiny = getTiny(mappings)
def reorderedMappings = reorder(mappings)
then:
mappings.srcNamespace == "named"
mappings.dstNamespaces == ["intermediary", "official"]
mappings.classes.size() == 5747
mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash
mappings.classes[0].getDstName(0) == "net/minecraft/class_2573"
mappings.classes[0].methods[0].args[0].srcName.hashCode() == 109757064
reorderedMappings.getClass("net/minecraft/class_2573").getMethod("method_10913", "(Lnet/minecraft/class_1799;Lnet/minecraft/class_1767;)V").args.size() > 0
}
}

View File

@@ -29,22 +29,22 @@ import net.fabricmc.loom.configuration.providers.mappings.file.FileMappingsSpecB
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
class UnpickLayerTest extends LayeredMappingsSpecification {
def "read unpick data from yarn"() {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
when:
def builder = FileMappingsSpecBuilderImpl.builder(FileSpec.create(YARN_1_17_URL)).containsUnpick()
def unpickData = getUnpickData(
new IntermediaryMappingsSpec(),
builder.build()
)
def metadata = unpickData.metadata()
then:
metadata.version() == 1
metadata.unpickGroup() == "net.fabricmc.unpick"
metadata.unpickVersion() == "2.2.0"
def "read unpick data from yarn"() {
setup:
intermediaryUrl = INTERMEDIARY_1_17_URL
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
when:
def builder = FileMappingsSpecBuilderImpl.builder(FileSpec.create(YARN_1_17_URL)).containsUnpick()
def unpickData = getUnpickData(
new IntermediaryMappingsSpec(),
builder.build()
)
def metadata = unpickData.metadata()
then:
metadata.version() == 1
metadata.unpickGroup() == "net.fabricmc.unpick"
metadata.unpickVersion() == "2.2.0"
unpickData.definitions().length == 56119
}
unpickData.definitions().length == 56119
}
}

View File

@@ -24,67 +24,65 @@
package net.fabricmc.loom.test.unit.processor
import spock.lang.Specification
import net.fabricmc.loom.api.processor.SpecContext
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor
import net.fabricmc.loom.test.util.GradleTestUtil
import net.fabricmc.loom.util.fmj.FabricModJson
import net.fabricmc.loom.util.fmj.ModEnvironment
import spock.lang.Specification
class AccessWidenerJarProcessorTest extends Specification {
def "Local AW"() {
given:
def specContext = Mock(SpecContext)
def file = new File("src/test/resources/accesswidener/AccessWidenerJarProcessorTest.accesswidener")
def localAccessWidenerProperty = GradleTestUtil.mockRegularFileProperty(file)
def "Local AW"() {
given:
def specContext = Mock(SpecContext)
def file = new File("src/test/resources/accesswidener/AccessWidenerJarProcessorTest.accesswidener")
def localAccessWidenerProperty = GradleTestUtil.mockRegularFileProperty(file)
def processor = new AccessWidenerJarProcessor("AccessWidener", true, localAccessWidenerProperty)
specContext.modDependencies() >> []
def processor = new AccessWidenerJarProcessor("AccessWidener", true, localAccessWidenerProperty)
specContext.modDependencies() >> []
when:
def spec = processor.buildSpec(specContext)
when:
def spec = processor.buildSpec(specContext)
then:
spec != null
}
then:
spec != null
}
def "Dep AW"() {
given:
def specContext = Mock(SpecContext)
def "Dep AW"() {
given:
def specContext = Mock(SpecContext)
def mod1 = Mock(FabricModJson.Mockable)
mod1.getClassTweakers() >> ["test.accesswidener": ModEnvironment.UNIVERSAL]
mod1.getId() >> "modid1"
def mod1 = Mock(FabricModJson.Mockable)
mod1.getClassTweakers() >> ["test.accesswidener": ModEnvironment.UNIVERSAL]
mod1.getId() >> "modid1"
def mod2 = Mock(FabricModJson.Mockable)
mod2.getClassTweakers() >> ["test2.accesswidener": ModEnvironment.UNIVERSAL]
mod2.getId() >> "modid2"
def mod2 = Mock(FabricModJson.Mockable)
mod2.getClassTweakers() >> ["test2.accesswidener": ModEnvironment.UNIVERSAL]
mod2.getId() >> "modid2"
specContext.modDependencies() >> [
mod1,
mod2
].shuffled()
specContext.modDependencies() >> [mod1, mod2].shuffled()
def processor = new AccessWidenerJarProcessor("AccessWidener", true, GradleTestUtil.mockRegularFileProperty(null))
def processor = new AccessWidenerJarProcessor("AccessWidener", true, GradleTestUtil.mockRegularFileProperty(null))
when:
def spec = processor.buildSpec(specContext)
when:
def spec = processor.buildSpec(specContext)
then:
spec != null
}
then:
spec != null
}
def "No AWs"() {
given:
def specContext = Mock(SpecContext)
specContext.modDependencies() >> []
def "No AWs"() {
given:
def specContext = Mock(SpecContext)
specContext.modDependencies() >> []
def processor = new AccessWidenerJarProcessor("AccessWidener", true, GradleTestUtil.mockRegularFileProperty(null))
def processor = new AccessWidenerJarProcessor("AccessWidener", true, GradleTestUtil.mockRegularFileProperty(null))
when:
def spec = processor.buildSpec(specContext)
when:
def spec = processor.buildSpec(specContext)
then:
spec == null
}
then:
spec == null
}
}

View File

@@ -24,47 +24,48 @@
package net.fabricmc.loom.test.unit.processor
import spock.lang.Specification
import net.fabricmc.loom.api.processor.ProcessorContext
import net.fabricmc.loom.api.processor.SpecContext
import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager
import net.fabricmc.loom.test.util.processor.TestMinecraftJarProcessor
import spock.lang.Specification
import static net.fabricmc.loom.test.util.ZipTestUtils.createZip
class MinecraftJarProcessorManagerTest extends Specification {
def "Does not require re-processing"() {
given:
def specContext = Mock(SpecContext)
def processorContext = Mock(ProcessorContext)
def "Does not require re-processing"() {
given:
def specContext = Mock(SpecContext)
def processorContext = Mock(ProcessorContext)
def processor1 = new TestMinecraftJarProcessor(input: "Test1")
def processor2 = new TestMinecraftJarProcessor(input: "Test2")
def manager = MinecraftJarProcessorManager.create([processor1, processor2], specContext)
def processor1 = new TestMinecraftJarProcessor(input: "Test1")
def processor2 = new TestMinecraftJarProcessor(input: "Test2")
def manager = MinecraftJarProcessorManager.create([processor1, processor2], specContext)
when:
def jar = createZip(["fabric.mod.json": "{}"])
manager.processJar(jar, processorContext)
when:
def jar = createZip(["fabric.mod.json": "{}"])
manager.processJar(jar, processorContext)
then:
!manager.requiresProcessingJar(jar)
}
then:
!manager.requiresProcessingJar(jar)
}
def "Requires re-processing"() {
given:
def specContext = Mock(SpecContext)
def processorContext = Mock(ProcessorContext)
def "Requires re-processing"() {
given:
def specContext = Mock(SpecContext)
def processorContext = Mock(ProcessorContext)
def processor1 = new TestMinecraftJarProcessor(input: "Test1")
def processor2 = new TestMinecraftJarProcessor(input: "Test2")
def manager1 = MinecraftJarProcessorManager.create([processor1], specContext)
def manager2 = MinecraftJarProcessorManager.create([processor1, processor2], specContext)
def processor1 = new TestMinecraftJarProcessor(input: "Test1")
def processor2 = new TestMinecraftJarProcessor(input: "Test2")
def manager1 = MinecraftJarProcessorManager.create([processor1], specContext)
def manager2 = MinecraftJarProcessorManager.create([processor1, processor2], specContext)
when:
def jar = createZip(["fabric.mod.json": "{}"])
manager1.processJar(jar, processorContext)
when:
def jar = createZip(["fabric.mod.json": "{}"])
manager1.processJar(jar, processorContext)
then:
manager2.requiresProcessingJar(jar)
}
then:
manager2.requiresProcessingJar(jar)
}
}

View File

@@ -24,27 +24,28 @@
package net.fabricmc.loom.test.unit.processor
import spock.lang.Specification
import net.fabricmc.loom.configuration.accesswidener.ModAccessWidenerEntry
import net.fabricmc.loom.util.fmj.FabricModJson
import net.fabricmc.loom.util.fmj.ModEnvironment
import spock.lang.Specification
class ModAccessWidenerEntryTest extends Specification {
def "read local mod"() {
given:
def mod = Mock(FabricModJson.Mockable)
mod.getClassTweakers() >> ["test.accesswidener": ModEnvironment.UNIVERSAL]
mod.hashCode() >> 0
def "read local mod"() {
given:
def mod = Mock(FabricModJson.Mockable)
mod.getClassTweakers() >> ["test.accesswidener": ModEnvironment.UNIVERSAL]
mod.hashCode() >> 0
when:
def entries = ModAccessWidenerEntry.readAll(mod, true)
then:
entries.size() == 1
def entry = entries[0]
when:
def entries = ModAccessWidenerEntry.readAll(mod, true)
then:
entries.size() == 1
def entry = entries[0]
entry.path() == "test.accesswidener"
entry.environment() == ModEnvironment.UNIVERSAL
entry.transitiveOnly()
entry.hashCode() == -1218981396
}
entry.path() == "test.accesswidener"
entry.environment() == ModEnvironment.UNIVERSAL
entry.transitiveOnly()
entry.hashCode() == -1218981396
}
}

View File

@@ -25,232 +25,233 @@
package net.fabricmc.loom.test.util
import groovy.transform.Immutable
import net.fabricmc.loom.test.LoomTestConstants
import net.fabricmc.loom.util.Constants
import net.fabricmc.loom.util.ZipUtils
import org.apache.commons.io.FileUtils
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import spock.lang.Shared
import net.fabricmc.loom.test.LoomTestConstants
import net.fabricmc.loom.util.Constants
import net.fabricmc.loom.util.ZipUtils
trait GradleProjectTestTrait {
@Lazy
@Shared
private static File sharedProjectDir = File.createTempDir()
private static File gradleHomeDir = new File(LoomTestConstants.TEST_DIR, "integration/gradle_home")
@Lazy
@Shared
private static File sharedProjectDir = File.createTempDir()
private static File gradleHomeDir = new File(LoomTestConstants.TEST_DIR, "integration/gradle_home")
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 = gradleHomeDir
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 = gradleHomeDir
setupProject(options, projectDir)
setupProject(options, projectDir)
println([
projectDir: projectDir.absolutePath,
gradleHomeDir: gradleHomeDir.absolutePath
])
println([
projectDir: projectDir.absolutePath,
gradleHomeDir: gradleHomeDir.absolutePath
])
return new GradleProject(
gradleVersion: gradleVersion,
projectDir: projectDir.absolutePath,
gradleHomeDir: gradleHomeDir.absolutePath,
warningMode: warningMode
)
}
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
}
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
if (options.repo) {
String repo = options.repo
String commit = options.commit
if (options.allowExistingRepo && projectDir.listFiles()?.length > 0) {
return
}
if (options.allowExistingRepo && projectDir.listFiles()?.length > 0) {
return
}
exec(projectDir, "git", "clone", repo, ".")
exec(projectDir, "git", "checkout", commit)
exec(projectDir, "git", "clone", repo, ".")
exec(projectDir, "git", "checkout", commit)
if (options.patch) {
def patchFile = new File("src/test/resources/patches/${options.patch}.patch")
if (options.patch) {
def patchFile = new File("src/test/resources/patches/${options.patch}.patch")
if (!patchFile.exists()) {
throw new FileNotFoundException("Could not find patch file at: " + patchFile.absolutePath)
}
if (!patchFile.exists()) {
throw new FileNotFoundException("Could not find patch file at: " + patchFile.absolutePath)
}
exec(projectDir, "git", "apply", patchFile.absolutePath)
}
exec(projectDir, "git", "apply", patchFile.absolutePath)
}
return
}
return
}
throw new UnsupportedOperationException("No project setup method was supplied")
}
throw new UnsupportedOperationException("No project setup method was supplied")
}
private void exec(File projectDir, String... args) {
projectDir.mkdirs()
def process = args.execute([], projectDir)
process.consumeProcessOutput(System.out, System.err)
private void exec(File projectDir, String... args) {
projectDir.mkdirs()
def process = args.execute([], projectDir)
process.consumeProcessOutput(System.out, System.err)
def exitCode = process.waitFor()
def exitCode = process.waitFor()
if (exitCode != 0) {
throw new RuntimeException("Command failed with exit code: $exitCode")
}
}
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")
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")
}
if (!projectSourceDir.exists()) {
throw new FileNotFoundException("Failed to find project directory at: $projectSourceDir.absolutePath")
}
def settingsGradle = new File(projectDir, "settings.gradle")
def settingsGradle = new File(projectDir, "settings.gradle")
// Cleanup some basic things if they already exists
new File(projectDir, "src").deleteDir()
new File(projectDir, "build.gradle").delete()
settingsGradle.delete()
// Cleanup some basic things if they already exists
new File(projectDir, "src").deleteDir()
new File(projectDir, "build.gradle").delete()
settingsGradle.delete()
projectSourceDir.eachFileRecurse { file ->
if (file.isDirectory()) {
return
}
projectSourceDir.eachFileRecurse { file ->
if (file.isDirectory()) {
return
}
def path = file.path.replace(projectSourceDir.path, "")
def path = file.path.replace(projectSourceDir.path, "")
File tempFile = new File(projectDir, path)
File tempFile = new File(projectDir, path)
if (tempFile.exists()) {
tempFile.delete()
}
if (tempFile.exists()) {
tempFile.delete()
}
tempFile.parentFile.mkdirs()
tempFile.bytes = file.bytes
}
tempFile.parentFile.mkdirs()
tempFile.bytes = file.bytes
}
if (!settingsGradle.exists()) {
settingsGradle.createNewFile()
}
}
if (!settingsGradle.exists()) {
settingsGradle.createNewFile()
}
}
@Immutable
static class GradleProject {
private String gradleVersion
private String projectDir
private String gradleHomeDir
private String warningMode
private boolean useBuildSrc
@Immutable
static class GradleProject {
private String gradleVersion
private String projectDir
private String gradleHomeDir
private String warningMode
private boolean useBuildSrc
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", mavenLocalDir.absolutePath)
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", mavenLocalDir.absolutePath)
def runner = this.runner
def args = []
def runner = this.runner
def args = []
if (options.task) {
args << options.task
}
if (options.task) {
args << options.task
}
args.addAll(options.tasks ?: [])
args.addAll(options.tasks ?: [])
args << "--stacktrace"
args << "--stacktrace"
args << "--parallel"
args << "--warning-mode" << warningMode
args << "--gradle-user-home" << gradleHomeDir
args.addAll(options.args ?: [])
args << "--warning-mode" << warningMode
args << "--gradle-user-home" << gradleHomeDir
args.addAll(options.args ?: [])
runner.withArguments(args as String[])
runner.withArguments(args as String[])
if (useBuildSrc) {
writeBuildSrcDeps(runner)
}
if (useBuildSrc) {
writeBuildSrcDeps(runner)
}
return options.expectFailure ? runner.buildAndFail() : runner.build()
}
return options.expectFailure ? runner.buildAndFail() : runner.build()
}
private GradleRunner getRunner() {
return GradleRunner.create()
.withProjectDir(getProjectDir())
.withPluginClasspath()
.withGradleVersion(gradleVersion)
.forwardOutput()
.withDebug(true)
}
private GradleRunner getRunner() {
return GradleRunner.create()
.withProjectDir(getProjectDir())
.withPluginClasspath()
.withGradleVersion(gradleVersion)
.forwardOutput()
.withDebug(true)
}
File getProjectDir() {
return new File(projectDir)
}
File getProjectDir() {
return new File(projectDir)
}
File getGradleHomeDir() {
return new File(gradleHomeDir)
}
File getGradleHomeDir() {
return new File(gradleHomeDir)
}
File getOutputFile(String filename) {
return new File(getProjectDir(), "build/libs/$filename")
}
File getOutputFile(String filename) {
return new File(getProjectDir(), "build/libs/$filename")
}
File getMavenLocalDir() {
return new File(gradleHomeDir, "m2")
}
File getMavenLocalDir() {
return new File(gradleHomeDir, "m2")
}
void printOutputFiles() {
new File(getProjectDir(), "build/libs/").listFiles().each {
println(it.name)
}
}
void printOutputFiles() {
new File(getProjectDir(), "build/libs/").listFiles().each {
println(it.name)
}
}
File getBuildGradle() {
return new File(getProjectDir(), "build.gradle")
}
File getBuildGradle() {
return new File(getProjectDir(), "build.gradle")
}
File getGradleProperties() {
return new File(getProjectDir(), "gradle.properties")
}
File getGradleProperties() {
return new File(getProjectDir(), "gradle.properties")
}
String getOutputZipEntry(String filename, String entryName) {
def file = getOutputFile(filename)
def bytes = ZipUtils.unpackNullable(file.toPath(), entryName)
String getOutputZipEntry(String filename, String entryName) {
def file = getOutputFile(filename)
def bytes = ZipUtils.unpackNullable(file.toPath(), entryName)
if (bytes == null) {
throw new FileNotFoundException("Could not find ${entryName} in ${entryName}")
}
if (bytes == null) {
throw new FileNotFoundException("Could not find ${entryName} in ${entryName}")
}
new String(bytes as byte[])
}
new String(bytes as byte[])
}
boolean hasOutputZipEntry(String filename, String entryName) {
def file = getOutputFile(filename)
return ZipUtils.unpackNullable(file.toPath(), entryName) != null
}
boolean hasOutputZipEntry(String filename, String entryName) {
def file = getOutputFile(filename)
return ZipUtils.unpackNullable(file.toPath(), entryName) != null
}
File getGeneratedSources(String mappings) {
return new File(getGradleHomeDir(), "caches/fabric-loom/minecraftMaven/net/minecraft/minecraft-merged/${mappings}/minecraft-merged-${mappings}-sources.jar")
}
File getGeneratedSources(String mappings) {
return new File(getGradleHomeDir(), "caches/fabric-loom/minecraftMaven/net/minecraft/minecraft-merged/${mappings}/minecraft-merged-${mappings}-sources.jar")
}
File getGeneratedLocalSources(String mappings) {
return new File(getProjectDir(), ".gradle/loom-cache/minecraftMaven/net/minecraft/minecraft-merged-project-root/${mappings}/minecraft-merged-project-root-${mappings}-sources.jar")
}
File getGeneratedLocalSources(String mappings) {
return new File(getProjectDir(), ".gradle/loom-cache/minecraftMaven/net/minecraft/minecraft-merged-project-root/${mappings}/minecraft-merged-project-root-${mappings}-sources.jar")
}
void buildSrc(String name) {
useBuildSrc = true
void buildSrc(String name) {
useBuildSrc = true
def buildSrcDir = new File(projectDir, "buildSrc")
buildSrcDir.mkdirs()
def buildSrcDir = new File(projectDir, "buildSrc")
buildSrcDir.mkdirs()
def pluginClass = "net.fabricmc.loom.test.integration.buildSrc.${name}.TestPlugin"
new File(buildSrcDir, "build.gradle") << """
def pluginClass = "net.fabricmc.loom.test.integration.buildSrc.${name}.TestPlugin"
new File(buildSrcDir, "build.gradle") << """
plugins {
id 'groovy-gradle-plugin'
id 'groovy'
@@ -266,45 +267,45 @@ trait GradleProjectTestTrait {
}
"""
new File(buildSrcDir, "settings.gradle") << '''
new File(buildSrcDir, "settings.gradle") << '''
rootProject.name='loom-test-plugin'
'''
// Patch the new plugin into the end of the plugins block
def matcher = buildGradle.text =~ /(?s)plugins \{(?<ids>.*)}/
assert matcher.find()
def ids = matcher.group("ids")
// Patch the new plugin into the end of the plugins block
def matcher = buildGradle.text =~ /(?s)plugins \{(?<ids>.*)}/
assert matcher.find()
def ids = matcher.group("ids")
def pluginBlock = """
def pluginBlock = """
plugins {
${ids}
id 'loom-test-plugin'
}
"""
buildGradle.text = buildGradle.text.replaceAll("(?s)(plugins \\{.*})", pluginBlock)
buildGradle.text = buildGradle.text.replaceAll("(?s)(plugins \\{.*})", pluginBlock)
def sourceSrc = new File("src/test/groovy/net/fabricmc/loom/test/integration/buildSrc/" + name)
def targetSrc = new File(buildSrcDir, "src/main/groovy/net/fabricmc/loom/test/integration/buildSrc/" + name)
def sourceSrc = new File("src/test/groovy/net/fabricmc/loom/test/integration/buildSrc/" + name)
def targetSrc = new File(buildSrcDir, "src/main/groovy/net/fabricmc/loom/test/integration/buildSrc/" + name)
FileUtils.copyDirectory(sourceSrc, targetSrc)
}
FileUtils.copyDirectory(sourceSrc, targetSrc)
}
void writeBuildSrcDeps(GradleRunner runner) {
def dependencies = ""
runner.pluginClasspath.forEach { File file ->
dependencies += "implementation files('${file.absolutePath.replace("\\", "\\\\")}')\n"
}
void writeBuildSrcDeps(GradleRunner runner) {
def dependencies = ""
runner.pluginClasspath.forEach { File file ->
dependencies += "implementation files('${file.absolutePath.replace("\\", "\\\\")}')\n"
}
new File(projectDir, "buildSrc/build.gradle") << """
new File(projectDir, "buildSrc/build.gradle") << """
dependencies {
${dependencies}
}
"""
}
}
void enableMultiProjectOptimisation() {
getGradleProperties() << "\n${Constants.Properties.MULTI_PROJECT_OPTIMISATION}=true"
}
}
}
}

View File

@@ -24,7 +24,6 @@
package net.fabricmc.loom.test.util
import net.fabricmc.loom.LoomGradleExtension
import org.gradle.api.Project
import org.gradle.api.file.RegularFile
import org.gradle.api.file.RegularFileProperty
@@ -37,21 +36,23 @@ import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.util.PatternFilterable
import org.jetbrains.annotations.Nullable
import net.fabricmc.loom.LoomGradleExtension
import static org.mockito.ArgumentMatchers.any
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
class GradleTestUtil {
static <T> Property<T> mockProperty(T value) {
def mock = mock(Property.class)
when(mock.get()).thenReturn(Objects.requireNonNull(value))
return mock
}
static <T> Property<T> mockProperty(T value) {
def mock = mock(Property.class)
when(mock.get()).thenReturn(Objects.requireNonNull(value))
return mock
}
static SourceSet mockSourceSet(String name) {
def sourceSet = new DefaultSourceSet(name, mockObjectFactory()) {
final ExtensionContainer extensions = null
}
final ExtensionContainer extensions = null
}
return sourceSet
}

View File

@@ -28,62 +28,62 @@ import io.javalin.Javalin
import org.apache.commons.io.IOUtils
trait MockMavenServerTrait {
public final int mavenServerPort = 9876
public final File testMavenDir = File.createTempDir()
private Javalin server
public final int mavenServerPort = 9876
public final File testMavenDir = File.createTempDir()
private Javalin server
@SuppressWarnings('unused')
def setupSpec() {
println "Maven server path: ${testMavenDir.absolutePath}"
@SuppressWarnings('unused')
def setupSpec() {
println "Maven server path: ${testMavenDir.absolutePath}"
server = Javalin.create { config ->
}.start(mavenServerPort)
server = Javalin.create { config ->
}.start(mavenServerPort)
/**
* A very very basic maven server impl, DO NOT copy this and use in production as its not secure
*/
server.get("*") { ctx ->
println "GET: " + ctx.path()
File file = getMavenPath(ctx.path())
/**
* A very very basic maven server impl, DO NOT copy this and use in production as its not secure
*/
server.get("*") { ctx ->
println "GET: " + ctx.path()
File file = getMavenPath(ctx.path())
if (!file.exists()) {
ctx.status(404)
return
}
if (!file.exists()) {
ctx.status(404)
return
}
ctx.result(file.bytes)
}
ctx.result(file.bytes)
}
server.put("*") { ctx ->
println "PUT: " + ctx.path()
File file = getMavenPath(ctx.path())
file.parentFile.mkdirs()
server.put("*") { ctx ->
println "PUT: " + ctx.path()
File file = getMavenPath(ctx.path())
file.parentFile.mkdirs()
file.withOutputStream {
IOUtils.copy(ctx.bodyInputStream(), it)
}
}
}
file.withOutputStream {
IOUtils.copy(ctx.bodyInputStream(), it)
}
}
}
@SuppressWarnings('unused')
def setup() {
System.setProperty('loom.test.mavenPort', port())
}
@SuppressWarnings('unused')
def setup() {
System.setProperty('loom.test.mavenPort', port())
}
@SuppressWarnings('unused')
def cleanupSpec() {
server.stop()
}
@SuppressWarnings('unused')
def cleanupSpec() {
server.stop()
}
File getMavenDirectory() {
new File(testMavenDir, "maven")
}
File getMavenDirectory() {
new File(testMavenDir, "maven")
}
File getMavenPath(String path) {
new File(getMavenDirectory(), path)
}
File getMavenPath(String path) {
new File(getMavenDirectory(), path)
}
String port() {
"${mavenServerPort}"
}
String port() {
"${mavenServerPort}"
}
}

View File

@@ -24,178 +24,179 @@
package net.fabricmc.loom.test.util
import groovy.transform.Immutable
import net.fabricmc.loom.util.download.Download
import java.util.concurrent.TimeUnit
import groovy.transform.Immutable
import net.fabricmc.loom.util.download.Download
class ServerRunner {
static final String LOADER_VERSION = "0.14.12"
static final String LOADER_VERSION = "0.14.12"
static final String INSTALLER_VERSION = "0.11.1"
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"
]
static final String FABRIC_LANG_KOTLIN = "https://maven.fabricmc.net/net/fabricmc/fabric-language-kotlin/1.8.5%2Bkotlin.1.7.20/fabric-language-kotlin-1.8.5%2Bkotlin.1.7.20.jar"
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"
]
static final String FABRIC_LANG_KOTLIN = "https://maven.fabricmc.net/net/fabricmc/fabric-language-kotlin/1.8.5%2Bkotlin.1.7.20/fabric-language-kotlin-1.8.5%2Bkotlin.1.7.20.jar"
final File serverDir
final String minecraftVersion
final File serverDir
final String minecraftVersion
final List<File> mods = []
final List<File> mods = []
private ServerRunner(File serverDir, String minecraftVersion) {
this.serverDir = serverDir
this.minecraftVersion = minecraftVersion
private ServerRunner(File serverDir, String minecraftVersion) {
this.serverDir = serverDir
this.minecraftVersion = minecraftVersion
this.serverDir.mkdirs()
}
this.serverDir.mkdirs()
}
static ServerRunner create(File testProjectDir, String minecraftVersion) {
return new ServerRunner(new File(testProjectDir, "server"), minecraftVersion)
}
static ServerRunner create(File testProjectDir, String minecraftVersion) {
return new ServerRunner(new File(testProjectDir, "server"), minecraftVersion)
}
def install() {
def install() {
def url = "https://meta.fabricmc.net/v2/versions/loader/${minecraftVersion}/${LOADER_VERSION}/${INSTALLER_VERSION}/server/jar"
Download.create(url)
.downloadPath(serverDir.toPath().resolve("fabric-server-launch.jar"))
.downloadPath(serverDir.toPath().resolve("fabric-server-launch.jar"))
def eulaFile = new File(serverDir, "eula.txt")
eulaFile << "eula=true"
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
}
def serverPropsFile = new File(serverDir, "server.properties")
serverPropsFile << "level-type=FLAT" // Generates the world faster
}
ServerRunner withMod(File file) {
mods << file
return this
}
ServerRunner withMod(File file) {
mods << file
return this
}
ServerRunner downloadMod(String url, String filename) {
File modFile = new File(serverDir, "downloadedMods/" + filename)
modFile.parentFile.mkdirs()
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
println("Downloading " + url)
modFile.bytes = new URL(url).bytes
return withMod(modFile)
}
return withMod(modFile)
}
ServerRunner withFabricApi() {
if (!FABRIC_API_URLS[minecraftVersion]) {
throw new UnsupportedOperationException("No Fabric api url for " + minecraftVersion)
}
ServerRunner withFabricApi() {
if (!FABRIC_API_URLS[minecraftVersion]) {
throw new UnsupportedOperationException("No Fabric api url for " + minecraftVersion)
}
return downloadMod(FABRIC_API_URLS[minecraftVersion], "fabricapi.jar")
}
return downloadMod(FABRIC_API_URLS[minecraftVersion], "fabricapi.jar")
}
ServerRunResult run() {
install()
ServerRunResult run() {
install()
// Copy the mods here so we can
mods.each {
if (!it.exists()) {
throw new FileNotFoundException(it.absolutePath)
}
// 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
}
File modFile = new File(serverDir, "mods/" + it.name)
modFile.parentFile.mkdirs()
modFile.bytes = it.bytes
}
String javaExecutablePath = ProcessHandle.current()
.info()
.command()
.orElseThrow()
String javaExecutablePath = ProcessHandle.current()
.info()
.command()
.orElseThrow()
var builder = new ProcessBuilder()
builder.directory(serverDir)
builder.command(javaExecutablePath, "-Xmx1G", "-jar", "fabric-server-launch.jar", "nogui")
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 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
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)
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])
)
println("Sending stop command")
process.outputStream.withCloseable {
it.write("stop\n".bytes)
}
}
}
}),
new ForwardingAppendable([System.err, out])
)
addShutdownHook {
if (process.alive) {
process.destroy()
}
}
addShutdownHook {
if (process.alive) {
process.destroy()
}
}
assert process.waitFor(10, TimeUnit.MINUTES)
int exitCode = process.exitValue()
assert process.waitFor(10, TimeUnit.MINUTES)
int exitCode = process.exitValue()
println("Sever closed with exit code: " + exitCode)
println("Sever closed with exit code: " + exitCode)
return new ServerRunResult(exitCode, out.toString())
}
return new ServerRunResult(exitCode, out.toString())
}
@Immutable
class ServerRunResult {
int exitCode
String output
@Immutable
class ServerRunResult {
int exitCode
String output
boolean successful() {
return exitCode == 0 && output.contains("Done ")
}
}
boolean successful() {
return exitCode == 0 && output.contains("Done ")
}
}
private class ForwardingAppendable implements Appendable {
final List<Appendable> appendables
final Closure onAppended
private class ForwardingAppendable implements Appendable {
final List<Appendable> appendables
final Closure onAppended
ForwardingAppendable(List<Appendable> appendables, Closure onAppended = {}) {
this.appendables = appendables
this.onAppended = 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)
}
@Override
Appendable append(CharSequence csq) throws IOException {
appendables.each {
it.append(csq)
}
onAppended.run()
return this
}
onAppended.run()
return this
}
@Override
Appendable append(CharSequence csq, int start, int end) throws IOException {
appendables.each {
it.append(csq, start, end)
}
@Override
Appendable append(CharSequence csq, int start, int end) throws IOException {
appendables.each {
it.append(csq, start, end)
}
onAppended.run()
return this
}
onAppended.run()
return this
}
@Override
Appendable append(char c) throws IOException {
appendables.each {
it.append(c)
}
@Override
Appendable append(char c) throws IOException {
appendables.each {
it.append(c)
}
onAppended.run()
return this
}
}
onAppended.run()
return this
}
}
}

View File

@@ -24,38 +24,38 @@
package net.fabricmc.loom.test.util
import net.fabricmc.loom.util.FileSystemUtil
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.util.jar.Attributes
import java.util.jar.Manifest
import net.fabricmc.loom.util.FileSystemUtil
class ZipTestUtils {
static Path createZip(Map<String, String> entries) {
def file = Files.createTempFile("loom-test", ".zip")
Files.delete(file)
static Path createZip(Map<String, String> entries) {
def file = Files.createTempFile("loom-test", ".zip")
Files.delete(file)
FileSystemUtil.getJarFileSystem(file, true).withCloseable { zip ->
entries.forEach { path, value ->
def fsPath = zip.getPath(path)
def fsPathParent = fsPath.getParent()
if (fsPathParent != null) Files.createDirectories(fsPathParent)
Files.writeString(fsPath, value, StandardCharsets.UTF_8)
}
}
FileSystemUtil.getJarFileSystem(file, true).withCloseable { zip ->
entries.forEach { path, value ->
def fsPath = zip.getPath(path)
def fsPathParent = fsPath.getParent()
if (fsPathParent != null) Files.createDirectories(fsPathParent)
Files.writeString(fsPath, value, StandardCharsets.UTF_8)
}
}
return file
}
return file
}
static String manifest(String key, String value) {
def manifest = new Manifest()
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0")
manifest.getMainAttributes().putValue(key, value)
static String manifest(String key, String value) {
def manifest = new Manifest()
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0")
manifest.getMainAttributes().putValue(key, value)
def out = new ByteArrayOutputStream()
manifest.write(out)
return out.toString(StandardCharsets.UTF_8)
}
def out = new ByteArrayOutputStream()
manifest.write(out)
return out.toString(StandardCharsets.UTF_8)
}
}

View File

@@ -24,34 +24,35 @@
package net.fabricmc.loom.test.util.processor
import java.nio.file.Path
import groovy.transform.Immutable
import net.fabricmc.loom.api.processor.MinecraftJarProcessor
import net.fabricmc.loom.api.processor.ProcessorContext
import net.fabricmc.loom.api.processor.SpecContext
import java.nio.file.Path
@Immutable
class TestMinecraftJarProcessor implements MinecraftJarProcessor<Spec> {
String input
String input
final String name = "TestProcessor"
final String name = "TestProcessor"
@Override
Spec buildSpec(SpecContext context) {
if (input == null) {
return null
}
@Override
Spec buildSpec(SpecContext context) {
if (input == null) {
return null
}
return new Spec(input)
}
return new Spec(input)
}
@Immutable
class Spec implements MinecraftJarProcessor.Spec {
String input
}
@Immutable
class Spec implements MinecraftJarProcessor.Spec {
String input
}
@Override
void processJar(Path jar, Spec spec, ProcessorContext context) throws IOException {
}
@Override
void processJar(Path jar, Spec spec, ProcessorContext context) throws IOException {
}
}

View File

@@ -11,11 +11,11 @@ version = project.mod_version
group = project.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}
loom {
@@ -55,7 +55,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}
@@ -79,12 +79,12 @@ publishing {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}

View File

@@ -51,7 +51,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}

View File

@@ -51,7 +51,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}

View File

@@ -1,15 +1,15 @@
pluginManagement {
plugins {
id 'fabric-loom'
}
plugins {
id 'fabric-loom'
}
}
plugins {
id 'fabric-loom'
id 'fabric-loom'
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
}
include 'basic'

View File

@@ -11,11 +11,11 @@ version = project.mod_version
group = project.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
flatDir {
dirs "myFlatDir"
}
@@ -59,7 +59,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}
@@ -83,12 +83,12 @@ publishing {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}

View File

@@ -11,11 +11,11 @@ version = loom.modVersion
group = project.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}
dependencies {
@@ -44,7 +44,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}
@@ -68,12 +68,12 @@ publishing {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}

View File

@@ -40,10 +40,10 @@ publishing {
}
}
repositories {
repositories {
maven {
url "http://localhost:${System.getProperty("loom.test.mavenPort")}/"
allowInsecureProtocol = true
}
}
}
}

View File

@@ -1,10 +1,10 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
mavenLocal()
}
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
mavenLocal()
}
}

View File

@@ -1,10 +1,10 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
mavenLocal()
}
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
mavenLocal()
}
}

View File

@@ -11,11 +11,11 @@ version = project.mod_version
group = project.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}
dependencies {
@@ -51,7 +51,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}
@@ -75,12 +75,12 @@ publishing {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}

View File

@@ -35,7 +35,7 @@ tasks.withType(JavaCompile).configureEach {
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}

View File

@@ -37,12 +37,12 @@ publishing {
}
}
repositories {
repositories {
maven {
url "http://localhost:${System.getProperty("loom.test.mavenPort")}/"
allowInsecureProtocol = true
}
}
}
}
signing {

View File

@@ -11,11 +11,11 @@ version = loom.modVersion
group = project.maven_group
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}
dependencies {
@@ -46,7 +46,7 @@ tasks.withType(JavaCompile).configureEach {
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = targetVersion
it.options.release = targetVersion
}
}
@@ -70,12 +70,12 @@ publishing {
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}