use
5.008001;
use
TestUtils
qw/exception pushd tempd has_symlinks/
;
my
$rel1
= path(
"."
);
my
$abs1
=
$rel1
->absolute;
is(
$abs1
->absolute,
$abs1
,
"absolute of absolute is identity"
);
my
$rel2
=
$rel1
->child(
"t"
);
my
$abs2
=
$rel2
->absolute;
is(
$rel2
->absolute(
$abs1
),
$abs2
,
"absolute on base"
);
my
@symlink_free_cases
= (
[
"A->rel(A)"
,
"/foo/bar"
,
"/foo/bar"
,
"."
],
[
"a->rel(a)"
,
"foo/bar"
,
"foo/bar"
,
"."
],
[
"AB->rel(A)"
,
"/foo/bar/baz"
,
"/"
,
"foo/bar/baz"
],
[
"AB->rel(A)"
,
"/foo/bar/baz"
,
"/foo"
,
"bar/baz"
],
[
"AB->rel(A)"
,
"/foo/bar/baz"
,
"/foo/bar"
,
"baz"
],
[
"ab->rel(a)"
,
"foo/bar/baz"
,
""
,
"foo/bar/baz"
],
[
"ab->rel(a)"
,
"foo/bar/baz"
,
"."
,
"foo/bar/baz"
],
[
"ab->rel(a)"
,
"foo/bar/baz"
,
"foo"
,
"bar/baz"
],
[
"ab->rel(a)"
,
"foo/bar/baz"
,
"foo/bar"
,
"baz"
],
[
"R->rel(A)"
,
"/"
,
"/bam"
,
".."
],
[
"R->rel(AB)"
,
"/"
,
"/bam/baz"
,
"../.."
],
[
"ABC->rel(D)"
,
"/foo/bar/baz"
,
"/bam"
,
"../foo/bar/baz"
],
[
"ABC->rel(AD)"
,
"/foo/bar/baz"
,
"/foo/bam"
,
"../bar/baz"
],
[
"ABC->rel(ABD)"
,
"/foo/bar/baz"
,
"/foo/bar/bam"
,
"../baz"
],
[
"ABC->rel(DE)"
,
"/foo/bar/baz"
,
"/bim/bam"
,
"../../foo/bar/baz"
],
[
"ABC->rel(ADE)"
,
"/foo/bar/baz"
,
"/foo/bim/bam"
,
"../../bar/baz"
],
[
"ABC->rel(ABDE)"
,
"/foo/bar/baz"
,
"/foo/bar/bim/bam"
,
"../../baz"
],
[
"abc->rel(d)"
,
"foo/bar/baz"
,
"bam"
,
"../foo/bar/baz"
],
[
"abc->rel(ad)"
,
"foo/bar/baz"
,
"foo/bam"
,
"../bar/baz"
],
[
"abc->rel(abd)"
,
"foo/bar/baz"
,
"foo/bar/bam"
,
"../baz"
],
[
"abc->rel(de)"
,
"foo/bar/baz"
,
"bim/bam"
,
"../../foo/bar/baz"
],
[
"abc->rel(ade)"
,
"foo/bar/baz"
,
"foo/bim/bam"
,
"../../bar/baz"
],
[
"abc->rel(abde)"
,
"foo/bar/baz"
,
"foo/bar/bim/bam"
,
"../../baz"
],
[
"ab->rel(a)"
,
"foo/bar"
,
"foo"
,
"bar"
],
[
"abc->rel(ab)"
,
"foo/bar/baz"
,
"foo/bim"
,
"../bar/baz"
],
[
"a->rel(b)"
,
"foo"
,
"bar"
,
"../foo"
],
);
for
my
$c
(
@symlink_free_cases
) {
my
(
$label
,
$path
,
$base
,
$result
) =
@$c
;
is( path(
$path
)->relative(
$base
),
$result
,
$label
);
}
my
@one_rel_from_root
= (
[
"A->rel(b) from rootdir"
,
"/foo/bar"
,
"baz"
,
"../foo/bar"
],
[
"a->rel(B) from rootdir"
,
"foo/bar"
,
"/baz"
,
"../foo/bar"
],
);
{
my
$wd
= pushd(
"/"
);
for
my
$c
(
@one_rel_from_root
) {
my
(
$label
,
$path
,
$base
,
$result
) =
@$c
;
is( path(
$path
)->relative(
$base
),
$result
,
$label
);
}
}
{
my
$wd
= tempd(
"/"
);
my
$cwd
= Path::Tiny::cwd->realpath;
my
$base
=
$cwd
->child(
"baz"
);
my
(
undef
,
@parts
) =
split
"/"
,
$base
;
my
$up_to_root
= path(
"../"
x
@parts
);
is(
path(
"/foo/bar"
)->relative(
"baz"
),
$up_to_root
->child(
"foo/bar"
),
"A->rel(b) from tmpdir"
);
is(
path(
"foo/bar"
)->relative(
"/baz"
),
path(
".."
,
$cwd
->_just_filepath,
"foo/bar"
),
"a->rel(B) from tmpdir"
);
}
subtest
"relative on absolute paths with symlinks"
=>
sub
{
my
$wd
= tempd;
my
$cwd
= path(
"."
)->realpath;
my
$deep
=
$cwd
->child(
"foo/bar/baz/bam/bim/buz/wiz/was/woz"
);
$deep
->mkpath();
plan
skip_all
=>
"No symlink support"
unless
has_symlinks();
my
(
$path
,
$base
,
$expect
);
$cwd
->child(
"A"
)->mkpath;
symlink
$deep
,
"A/B"
or
die
"$!"
;
$path
=
$cwd
->child(
"A/B/C/D"
);
$path
->mkpath;
is(
$path
->relative(
$cwd
->child(
"A/B/E/F"
) ),
"../../C/D"
,
"A_BCD->rel(A_BEF)"
);
$cwd
->child(
"A"
)->remove_tree;
$deep
->remove_tree;
$deep
->mkpath;
$cwd
->child(
"A/B/C"
)->mkpath;
symlink
$deep
,
"A/B/C/D"
or
die
"$!"
;
$path
=
$cwd
->child(
"A/B/C/D/E"
);
$path
->mkpath;
is(
$path
->relative(
$cwd
->child(
"A/B/F/G"
) ),
"../../C/D/E"
,
"ABC_DE->rel(ABC_FG)"
);
$cwd
->child(
"A"
)->remove_tree;
$deep
->remove_tree;
$deep
->mkpath;
$path
=
$cwd
->child(
"A/B/C/D"
);
$path
->mkpath;
$cwd
->child(
"A/B/E"
)->mkpath;
symlink
$deep
,
"A/B/E/F"
or
die
$!;
$base
=
$cwd
->child(
"A/B/E/F/G"
);
$base
->mkpath;
$expect
=
$path
->relative(
$deep
->child(
"G"
) );
is(
$path
->relative(
$base
),
$expect
,
"ABCD->rel(ABE_FG) [real paths]"
);
$cwd
->child(
"A"
)->remove_tree;
$deep
->remove_tree;
$deep
->mkpath;
$path
=
$cwd
->child(
"A/B/C/D"
);
$path
->mkpath;
$cwd
->child(
"A/B/E"
)->mkpath;
symlink
$deep
,
"A/B/E/F"
or
die
$!;
$base
=
$cwd
->child(
"A/B/E/F/G/H"
);
$expect
=
$path
->relative(
$deep
->child(
"G/H"
) );
is(
$path
->relative(
$base
),
$expect
,
"ABCD->rel(ABE_FGH) [unreal paths]"
);
$cwd
->child(
"A"
)->remove_tree;
$deep
->remove_tree;
$deep
->mkpath;
$cwd
->child(
"A/B"
)->mkpath;
symlink
$deep
,
"A/B/C"
or
die
"$!"
;
$path
=
$cwd
->child(
"A/B/C/D/E"
);
$path
->mkpath;
$base
=
$cwd
->child(
"A/B/C/../F/G"
);
$base
->mkpath;
$expect
=
$path
->relative(
$deep
->parent->child(
"F/G"
)->realpath );
is(
$path
->relative(
$base
),
$expect
,
"AB_CDE->rel(AB_C..FG)"
);
$cwd
->child(
"A"
)->remove_tree;
$deep
->remove_tree;
$deep
->mkpath;
$path
=
$cwd
->child(
"A/B/C/D/E"
);
$path
->mkpath;
$cwd
->child(
"A/B/F"
)->mkpath;
$cwd
->child(
"A/B/G/H"
)->mkpath;
$base
=
$cwd
->child(
"A/B/F/../G/H"
);
$expect
=
"../../C/D/E"
;
is(
$path
->relative(
$base
),
$expect
,
"ABCDE->rel(ABF..GH) [real paths]"
);
$cwd
->child(
"A"
)->remove_tree;
$path
=
$cwd
->child(
"A/B/C/D/E"
);
$base
=
$cwd
->child(
"A/B/F/../G/H"
);
$expect
=
"../../C/D/E"
;
is(
$path
->relative(
$base
),
$expect
,
"ABCDE->rel(ABF..GH) [unreal paths]"
);
$cwd
->child(
"A"
)->remove_tree;
};
done_testing;