[英]Bug in Path's .relativize() documentation or am I doing something blatantly wrong here?
OK well, here is something fun. 好吧,这很有趣。 Note that "elements" here is an instance of
PathElements
, and for these .resolve()
and .relativize()
are fully tested and known to work ... Links to the relevant method implementations Path.resolve()
, Path.relativize()
请注意,“元素”这里是一个实例
PathElements
,并为这些.resolve()
和.relativize()
都经过全面测试并已知可以使用 ...链接到相关的方法实现Path.resolve()
Path.relativize()
Extract of the test method that fails: 失败的测试方法的摘录:
/*
* 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();
}
This test fails with: 该测试失败并显示:
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
And obviously so! 显然是这样!
And this is always false in this scenario. 在这种情况下,这始终是错误的。
So, is this a blatant bug in the documentation or am I overlooking something? 那么,这是文档中的一个公然错误还是我忽略了什么?
A: The documentation does not mention Paths from other filesystem. 答:该文档没有提及其他文件系统的路径。
The documentation for resolve and relativize is not perfectly clear here. 解决和相对化的文档在这里不是很清楚。 But in case were the argument path is from a different filesystem resolve and relativize must throw ProviderMismatchException.
但是,如果参数路径来自其他文件系统,则解析和相对化必须抛出ProviderMismatchException。 Your test should throw earlier.
您的测试应该提早进行。
The constraints on a path can be quite different from filesystem to filesystem. 路径的约束在文件系统之间可能有很大的不同。 Consider the relativize case.
考虑相对论的情况。 What should a path look like that can walk from one filesystem to another disjoint filesystem ?
从一个文件系统到另一个不相交的文件系统应该走什么样的路径?
Note: I tested several FileSystem implementations and all throw in that case. 注意:我测试了几种FileSystem实现,在这种情况下全部抛出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.