Updated tests for PyRequirement: there are tests for requirement names, versions and extras. All previous tests have been saved but some of them were reworked and integrated into new ones.

This commit is contained in:
Semyon Proshev
2016-05-24 17:29:56 +03:00
parent 47b7d1b439
commit cdf6f7a26c
2 changed files with 267 additions and 9 deletions
@@ -25,7 +25,9 @@ public enum PyRequirementRelation {
GT(">"),
GTE(">="),
EQ("=="),
NE("!=");
NE("!="),
COMPATIBLE("~="),
STR_EQ("===");
@NotNull
private final String myValue;
@@ -15,16 +15,21 @@
*/
package com.jetbrains.python;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.packaging.PyPackage;
import com.jetbrains.python.packaging.PyRequirement;
import com.jetbrains.python.packaging.requirement.PyRequirementRelation;
import com.jetbrains.python.packaging.requirement.PyRequirementVersionSpec;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @author vlan
@@ -1037,24 +1042,231 @@ public class PyRequirementTest extends PyTestCase {
// TODO: a sdist or wheel format archive
// REQUIREMENT
// TODO: extras
// TODO: name normalization
// TODO: hashes
// TODO: multiline
// TODO: https://pip.pypa.io/en/stable/reference/pip_install/#per-requirement-overrides
// https://www.python.org/dev/peps/pep-0508/#names
public void testRequirement() {
assertEquals(new PyRequirement("Orange-Bioinformatics"), PyRequirement.fromString("Orange-Bioinformatics"));
assertEquals(new PyRequirement("MOCPy"), PyRequirement.fromString("MOCPy"));
assertEquals(new PyRequirement("score.webassets"), PyRequirement.fromString("score.webassets"));
assertEquals(new PyRequirement("pip_helpers"), PyRequirement.fromString("pip_helpers"));
assertEquals(new PyRequirement("Django"), PyRequirement.fromString("Django"));
assertEquals(new PyRequirement("django"), PyRequirement.fromString("django"));
assertEquals(new PyRequirement("pinax-utils"), PyRequirement.fromString("pinax-utils"));
assertEquals(new PyRequirement("no_limit_nester"), PyRequirement.fromString("no_limit_nester"));
assertEquals(new PyRequirement("Flask-Celery-py3"), PyRequirement.fromString("Flask-Celery-py3"));
}
public void testRequirementWithVersion() {
assertEquals(new PyRequirement("Django", "1.3.1"), PyRequirement.fromString("Django==1.3.1"));
// https://www.python.org/dev/peps/pep-0440/
public void testRequirementVersion() {
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5a20"));
assertEquals(new PyRequirement("MOCPy", "0.1.0.dev0"), PyRequirement.fromString("MOCPy==0.1.0.dev0"));
assertEquals(new PyRequirement("score.webassets", "0.2.3"), PyRequirement.fromString("score.webassets==0.2.3"));
assertEquals(new PyRequirement("pip_helpers", "0.5.post6"), PyRequirement.fromString("pip_helpers==0.5.post6"));
assertEquals(new PyRequirement("Django", "1.9rc1"), PyRequirement.fromString("Django==1.9rc1"));
assertEquals(new PyRequirement("django", "1!1"), PyRequirement.fromString("django==1!1"));
assertEquals(new PyRequirement("pinax-utils", "1.0b1.dev3"), PyRequirement.fromString("pinax-utils==1.0b1.dev3"));
assertEquals(new PyRequirement("Flask-Celery-py3", "0.1.*"), PyRequirement.fromString("Flask-Celery-py3==0.1.*"));
assertEquals(new PyRequirement("no_limit_nester", "1.0+local.version.10"),
PyRequirement.fromString("no_limit_nester==1.0+local.version.10"));
}
assertEquals(new PyRequirement("Django", Collections.singletonList(new PyRequirementVersionSpec(PyRequirementRelation.LT, "1.4"))),
PyRequirement.fromString(" Django < 1.4 "));
// https://www.python.org/dev/peps/pep-0440/#normalization
public void testRequirementAlternatePreReleaseVersion() {
assertEquals(new PyRequirement("Django", "1.9rc1"), PyRequirement.fromString("Django==1.9RC1"));
assertEquals(new PyRequirement("Django", Arrays.asList(new PyRequirementVersionSpec(PyRequirementRelation.LT, "1.4"),
new PyRequirementVersionSpec(PyRequirementRelation.GTE, "1.3.1"))),
PyRequirement.fromString(" Django < 1.4 , >= 1.3.1 "));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.a20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.a.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-a20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-a_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_a20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_a-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5alpha20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.alpha20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.alpha.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-alpha20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-alpha_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_alpha20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_alpha-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5beta20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.beta20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.beta.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-beta20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-beta_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_beta20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5b20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_beta-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5c20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.c20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.c.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-c20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-c_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_c20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_c-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5pre20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.pre20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.pre.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-pre20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-pre_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_pre20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_pre-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5preview20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.preview20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.preview.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-preview20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-preview_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_preview20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5rc20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_preview-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a0"), PyRequirement.fromString("Orange-Bioinformatics==2.5a"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a0"), PyRequirement.fromString("Orange-Bioinformatics==2.5.a"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a0"), PyRequirement.fromString("Orange-Bioinformatics==2.5-a"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a0"), PyRequirement.fromString("Orange-Bioinformatics==2.5_a"));
}
// https://www.python.org/dev/peps/pep-0440/#normalization
public void testRequirementAlternatePostReleaseVersion() {
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-post20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-post.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_post20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_post_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5post20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5post-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.r20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-r20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-r.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_r20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_r_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5r20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5r-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5.rev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-rev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-rev.20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_rev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_rev_20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5rev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5rev-20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post0"), PyRequirement.fromString("Orange-Bioinformatics==2.5.post"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post0"), PyRequirement.fromString("Orange-Bioinformatics==2.5-post"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post0"), PyRequirement.fromString("Orange-Bioinformatics==2.5_post"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post0"), PyRequirement.fromString("Orange-Bioinformatics==2.5post"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.post20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-20"));
}
// https://www.python.org/dev/peps/pep-0440/#normalization
public void testRequirementAlternateDevelopmentVersion() {
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.dev20"), PyRequirement.fromString("Orange-Bioinformatics==2.5-dev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.dev20"), PyRequirement.fromString("Orange-Bioinformatics==2.5_dev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.dev20"), PyRequirement.fromString("Orange-Bioinformatics==2.5dev20"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.dev0"), PyRequirement.fromString("Orange-Bioinformatics==2.5-dev"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.dev0"), PyRequirement.fromString("Orange-Bioinformatics==2.5_dev"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5.dev0"), PyRequirement.fromString("Orange-Bioinformatics==2.5dev"));
}
// https://www.python.org/dev/peps/pep-0440/#normalization
public void testRequirementAlternateLocalVersion() {
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5+local.version"),
PyRequirement.fromString("Orange-Bioinformatics==2.5+local-version"));
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5+local.version"),
PyRequirement.fromString("Orange-Bioinformatics==2.5+local_version"));
}
// https://www.python.org/dev/peps/pep-0440/#normalization
public void testRequirementAlternateVersionStart() {
assertEquals(new PyRequirement("Orange-Bioinformatics", "2.5a20"), PyRequirement.fromString("Orange-Bioinformatics==v2.5a20"));
assertEquals(new PyRequirement("MOCPy", "0.1.0.dev0"), PyRequirement.fromString("MOCPy==v0.1.0.dev0"));
assertEquals(new PyRequirement("score.webassets", "0.2.3"), PyRequirement.fromString("score.webassets==v0.2.3"));
assertEquals(new PyRequirement("pip_helpers", "0.5.post6"), PyRequirement.fromString("pip_helpers==v0.5.post6"));
assertEquals(new PyRequirement("Django", "1.9rc1"), PyRequirement.fromString("Django==v1.9rc1"));
assertEquals(new PyRequirement("django", "1!1"), PyRequirement.fromString("django==v1!1"));
assertEquals(new PyRequirement("pinax-utils", "1.0b1.dev3"), PyRequirement.fromString("pinax-utils==v1.0b1.dev3"));
assertEquals(new PyRequirement("no_limit_nester"), PyRequirement.fromString("no_limit_nester==v1.0+local.version.10"));
assertEquals(new PyRequirement("Flask-Celery-py3", "0.1.*"), PyRequirement.fromString("Flask-Celery-py3==v0.1.*"));
}
// https://www.python.org/dev/peps/pep-0440/#version-specifiers
public void testRequirementRelation() {
doRequirementRelationTest(PyRequirementRelation.LT, "1.4");
doRequirementRelationTest(PyRequirementRelation.LTE, "1.4");
doRequirementRelationTest(PyRequirementRelation.NE, "1.4");
doRequirementRelationTest(PyRequirementRelation.EQ, "1.4");
doRequirementRelationTest(PyRequirementRelation.GT, "1.4");
doRequirementRelationTest(PyRequirementRelation.GTE, "1.4");
doRequirementRelationTest(PyRequirementRelation.COMPATIBLE, "1.*");
doRequirementRelationTest(PyRequirementRelation.STR_EQ, "version");
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.EQ), Arrays.asList("2.8.1", "2.8.*"));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GTE), Arrays.asList("1.4", "1.3.1"));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GT, PyRequirementRelation.NE,
PyRequirementRelation.LT, PyRequirementRelation.EQ),
Arrays.asList("1.6", "1.9", "1.9.6", "2.0a0", "2.4rc1"));
// PY-14583
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.LTE, PyRequirementRelation.GTE,
PyRequirementRelation.LTE),
Arrays.asList("0.8.4", "0.8.99", "0.9.7", "0.9.99"));
}
// https://www.python.org/dev/peps/pep-0508/#extras
// PY-15674
public void testRequirementExtras() {
final String name = "MyProject1";
final List<PyRequirementRelation> relations = Collections.emptyList();
final List<String> versions = Collections.emptyList();
doRequirementRelationTest(name, "[PDF]", relations, versions);
doRequirementRelationTest(name, " [extra1, extra2]", relations, versions);
doRequirementRelationTest(name, "[security,tests]", relations, versions);
}
// https://www.python.org/dev/peps/pep-0508/#extras
// PY-15674
public void testRequirementExtrasAndRelation() {
final String extras1 = "[PDF]";
final String name1 = "MyPackage";
final String extras2 = " [foo, bar]";
final String name2 = "Fizzy";
final String extras3 = " [security,tests]";
final String name3 = "requests";
doRequirementRelationTest(name1, extras1, PyRequirementRelation.LT, "1.4");
doRequirementRelationTest(name2, extras2, PyRequirementRelation.LTE, "1.4");
doRequirementRelationTest(name3, extras3, PyRequirementRelation.NE, "1.4");
doRequirementRelationTest(name1, extras1, PyRequirementRelation.EQ, "1.4");
doRequirementRelationTest(name2, extras2, PyRequirementRelation.GT, "1.4");
doRequirementRelationTest(name3, extras3, PyRequirementRelation.GTE, "1.4");
doRequirementRelationTest(name1, extras1, PyRequirementRelation.COMPATIBLE, "1.*");
doRequirementRelationTest(name2, extras2, PyRequirementRelation.STR_EQ, "version");
doRequirementRelationTest(name3, extras3, Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.EQ),
Arrays.asList("2.8.1", "2.8.*"));
doRequirementRelationTest(name1, extras1, Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GTE),
Arrays.asList("1.4", "1.3.1"));
doRequirementRelationTest(name2, extras2, Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GT, PyRequirementRelation.NE,
PyRequirementRelation.LT, PyRequirementRelation.EQ),
Arrays.asList("1.6", "1.9", "1.9.6", "2.0a0", "2.4rc1"));
// PY-14583
doRequirementRelationTest(name3, extras3, Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.LTE, PyRequirementRelation.GTE,
PyRequirementRelation.LTE),
Arrays.asList("0.8.4", "0.8.99", "0.9.7", "0.9.99"));
}
// PY-6355
@@ -1117,4 +1329,48 @@ public class PyRequirementTest extends PyTestCase {
private static void doTest(@NotNull String options, boolean editable) {
assertEquals(new PyRequirement("MyProject1", null, options, editable), PyRequirement.fromString(options));
}
private static void doRequirementRelationTest(@NotNull PyRequirementRelation relation, @NotNull String version) {
doRequirementRelationTest("Django", null, Collections.singletonList(relation), Collections.singletonList(version));
}
private static void doRequirementRelationTest(@NotNull List<PyRequirementRelation> relations, @NotNull List<String> versions) {
doRequirementRelationTest("Django", null, relations, versions);
}
private static void doRequirementRelationTest(@NotNull String name,
@Nullable String extras,
@NotNull PyRequirementRelation relation,
@NotNull String version) {
doRequirementRelationTest(name, extras, Collections.singletonList(relation), Collections.singletonList(version));
}
private static void doRequirementRelationTest(@NotNull String name,
@Nullable String extras,
@NotNull List<PyRequirementRelation> relations,
@NotNull List<String> versions) {
assertEquals(versions.size(), relations.size());
final StringBuilder sb = new StringBuilder(name);
final List<PyRequirementVersionSpec> expectedVersionSpecs = new ArrayList<>();
if (extras != null) sb.append(extras);
final int initialLength = sb.length();
for (Pair<PyRequirementRelation, String> pair : ContainerUtil.zip(relations, versions)) {
final PyRequirementRelation relation = pair.getFirst();
final String version = pair.getSecond();
sb.append(relation).append(version).append(",");
expectedVersionSpecs.add(new PyRequirementVersionSpec(relation, version));
}
if (sb.length() != initialLength) {
sb.setLength(sb.length() - 1);
}
final String options = sb.toString();
assertEquals(new PyRequirement(name, options, expectedVersionSpecs), PyRequirement.fromString(options));
}
}