DefaultPluginVersionResolverTest.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.plugin.version.internal;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
import org.eclipse.aether.util.version.GenericVersionScheme;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Which versions are excluded when a plugin is resolved without a declared version.
*/
class DefaultPluginVersionResolverTest {
private final DefaultPluginVersionResolver resolver =
new DefaultPluginVersionResolver(null, null, null, new GenericVersionScheme());
/**
* A resolver for which every candidate passes the compatibility check, so the tests observe the
* selection order alone.
*/
private static DefaultPluginVersionResolver resolverAcceptingEveryVersion() throws Exception {
MavenPluginManager pluginManager = Mockito.mock(MavenPluginManager.class);
Mockito.when(pluginManager.getPluginDescriptor(Mockito.any(), Mockito.any(), Mockito.any()))
.thenReturn(new PluginDescriptor());
return new DefaultPluginVersionResolver(null, null, pluginManager, new GenericVersionScheme());
}
private static DefaultPluginVersionResolver.Versions versions(String release, String... available) {
DefaultPluginVersionResolver.Versions versions = new DefaultPluginVersionResolver.Versions();
versions.releaseVersion = release;
for (String version : available) {
versions.versions.put(version, null);
}
return versions;
}
private static String select(DefaultPluginVersionResolver resolver, DefaultPluginVersionResolver.Versions versions)
throws Exception {
DefaultPluginVersionResult result = new DefaultPluginVersionResult();
resolver.selectVersion(
result,
new DefaultPluginVersionRequest()
.setGroupId("org.apache.maven.plugins")
.setArtifactId("maven-it-plugin"),
versions);
return result.getVersion();
}
@ParameterizedTest
@ValueSource(
strings = {
"1.0-alpha-1",
"1.0-alpha1",
"1.0-beta-1",
"4.0.0-beta-1",
"1.0-milestone-1",
"1.0-M1",
"1.0-rc-1",
"1.0-rc1",
"1.0-cr1",
"1.0-b2", // short form, as GenericQualifiers reads it
"1.0.beta.1", // the scheme treats '.' and '-' as the same separator
"1.0_alpha_1",
"1.0-SNAPSHOT"
})
void preReleaseQualifiersAreExcluded(String version) {
assertTrue(resolver.isPreRelease(version), version + " should count as a pre-release");
}
@ParameterizedTest
@ValueSource(
strings = {
"1.0",
"1.0.1",
"3.15.0",
"4.0.0",
"33.7.0-jre", // vendor/classifier qualifier, not a pre-release
"1.0-arc", // contains "rc" but is not a release candidate
"1.0-sp1", // service pack: sorts *after* the release
"1.0-final", // alias of the release itself
"1.0-ga"
})
void releasesAreNotExcluded(String version) {
assertFalse(resolver.isPreRelease(version), version + " should not count as a pre-release");
}
@ParameterizedTest
@ValueSource(strings = {"", "-", "not-a-version"})
void unparseableVersionsAreNotExcluded(String version) {
assertFalse(resolver.isPreRelease(version), version + " should not count as a pre-release");
}
@Test
void stableVersionIsDetectedAmongPreReleases() {
DefaultPluginVersionResolver.Versions versions = new DefaultPluginVersionResolver.Versions();
versions.versions.put("2.0-beta-1", null);
versions.versions.put("2.0-beta-2", null);
assertFalse(resolver.hasStableVersion(versions), "only pre-releases available");
versions.versions.put("1.0-SNAPSHOT", null);
assertFalse(resolver.hasStableVersion(versions), "snapshots are not a stable fallback either");
versions.versions.put("1.0", null);
assertTrue(resolver.hasStableVersion(versions), "1.0 is a stable fallback");
}
@Test
void aStableVersionWinsOverThePreReleaseNamedByTheMetadata() throws Exception {
assertEquals(
"1.0",
select(resolverAcceptingEveryVersion(), versions("2.0-beta-1", "1.0", "2.0-beta-1")),
"metadata says 2.0-beta-1 is the RELEASE, but 1.0 is the newest stable one");
}
@Test
void theNewestStableVersionIsSelected() throws Exception {
assertEquals(
"1.2", select(resolverAcceptingEveryVersion(), versions("2.0-beta-1", "1.0", "1.2", "2.0-beta-1")));
}
@Test
void aPreReleaseIsUsedWhenNoStableVersionExists() throws Exception {
assertEquals(
"2.0-beta-2",
select(resolverAcceptingEveryVersion(), versions("2.0-beta-2", "2.0-beta-1", "2.0-beta-2")),
"a plugin that only ever published pre-releases must still resolve");
}
@Test
void aSnapshotIsTheLastResort() throws Exception {
assertEquals(
"1.0-SNAPSHOT",
select(resolverAcceptingEveryVersion(), versions("", "1.0-SNAPSHOT")),
"snapshots rank below pre-releases");
}
@Test
void aStableReleaseVersionIsTakenAsIs() throws Exception {
assertEquals(
"2.0",
select(resolverAcceptingEveryVersion(), versions("2.0", "1.0", "2.0")),
"no search is needed when the metadata already names a stable version");
}
}