繁体   English   中英

Path的.relativize()文档中的错误,还是我在这里公然做错了什么?

[英]Bug in Path's .relativize() documentation or am I doing something blatantly wrong here?

好吧,这很有趣。 请注意,“元素”这里是一个实例PathElements ,并为这些.resolve().relativize()经过全面测试已知可以使用 ...链接到相关的方法实现Path.resolve() Path.relativize()

失败的测试方法的摘录:

/*
 * This test this part of the Path's .relativize() method:
 *
 * <p> For any two {@link #normalize normalized} paths <i>p</i> and
 * <i>q</i>, where <i>q</i> does not have a root component,
 * <blockquote>
 * <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>))
 * .equals(</tt><i>q</i><tt>)</tt>
 * </blockquote>
 *
 * Unfortunately, that turns out NOT TO BE TRUE! Whether p is absolute or
 * relative, it is indeed the case that the path elements (root, names) are
 * the same but the filesystem DIFFERS.
 *
 * An as Path's .equals() requires that the two filesystems be equal in
 * order for two Paths to be equals, this contract can not be obeyed; or I
 * am doing something VERY wrong.
 */
@Test(enabled = false)
public void relativizeResolveRoundRobinWorks()
{
    /*
     * In order to set up the environment we define a mock
     * FileSystemProvider which both our mock filesystems will return when
     * .provider() is called.
     *
     * We also suppose that the same PathElementsFactory is used; while this
     * code is not written yet, there should be only one such factory per
     * FileSystemProvider anyway (which is fed into all generated FileSystem
     * instances -- at least that's the plan).
     *
     * Note that this test method assumes that .equals() and .hashCode() are
     * not implemented on GenericPath. As such we check that the FileSystem
     * is the same (this is required by Path's equals()) and that the path
     * elements are the same (this is this package's requirements).
     */
    final FileSystemProvider fsProvider = mock(FileSystemProvider.class);
    final PathElementsFactory elementsFactory
        = new UnixPathElementsFactory();
    final FileSystem fsForP = mock(FileSystem.class);
    final FileSystem fsForQ = mock(FileSystem.class);

    when(fsForP.provider()).thenReturn(fsProvider);
    when(fsForQ.provider()).thenReturn(fsProvider);

    /*
     * The path to be operated. As the contract says, it has no root
     * component.
     */
    final GenericPath q = new GenericPath(fsForQ, elementsFactory,
        new PathElements(null, new String[] { "q1", "q2" }));

    /*
     * The path against which both resolution and relativization are
     * performed. We take two versions of it: a non absolute one and an
     * absolute one.
     *
     * Note that since we use a UnixPathElementsFactory, we equate an
     * absolute path (or not) to a path which has a root component (or not).
     */
    GenericPath p;
    // "rr" as in "resolved, relativized"
    GenericPath rr;

    final CustomSoftAssertions soft = CustomSoftAssertions.create();

    /*
     * Try with the absolute version first...
     */
    p = new GenericPath(fsForP, elementsFactory,
        new PathElements("/", new String[] { "p1", "p2" }));
    rr = (GenericPath) p.relativize(p.resolve(q));

    soft.assertThat(rr.getFileSystem())
        .as("rr and q filesystems should be the same (p absolute)")
        .isSameAs(q.getFileSystem());
    soft.assertThat(rr.elements).hasSameContentsAs(q.elements);

    /*
     * Now with the non absolute version
     */
    p = new GenericPath(fsForP, elementsFactory,
        new PathElements(null, new String[] { "p1", "p2" }));
    rr = (GenericPath) p.relativize(p.resolve(q));

    soft.assertThat(rr.getFileSystem())
        .as("rr and q filesystems should be the same (p not absolute)")
        .isSameAs(q.getFileSystem());
    soft.assertThat(rr.elements).hasSameContentsAs(q.elements);

    soft.assertAll();
}

该测试失败并显示:

org.assertj.core.api.SoftAssertionError: 
The following 2 assertions failed:
1) [rr and q filesystems should be the same (p absolute)] 
Expecting:
 <Mock for FileSystem, hashCode: 1125642929>
and actual:
 <Mock for FileSystem, hashCode: 1497261280>
to refer to the same object
2) [rr and q filesystems should be the same (p not absolute)] 
Expecting:
 <Mock for FileSystem, hashCode: 1125642929>
and actual:
 <Mock for FileSystem, hashCode: 1497261280>
to refer to the same object

显然是这样!

  • r = p.resolve(q)将给出一个与p共享同一文件系统的路径,而不是q;
  • 因此,p.relativize(r)还将提供与p具有相同文件系统的Path;
  • 但Path合同要求,为了使两个路径相等,它们必须共享同一文件系统。

在这种情况下,这始终是错误的。

那么,这是文档中的一个公然错误还是我忽略了什么?

答:该文档没有提及其他文件系统的路径。

解决和相对化的文档在这里不是很清楚。 但是,如果参数路径来自其他文件系统,则解析和相对化必须抛出ProviderMismatchException。 您的测试应该提早进行。

路径的约束在文件系统之间可能有很大的不同。 考虑相对论的情况。 从一个文件系统到另一个不相交的文件系统应该走什么样的路径?

注意:我测试了几种FileSystem实现,在这种情况下全部抛出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM