Skip to content

Commit

Permalink
fix: Windows ancestor not yielding root with prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmah309 committed Nov 21, 2024
1 parent 2efd490 commit 1080378
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 46 deletions.
2 changes: 0 additions & 2 deletions lib/src/path/path.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'package:rust/src/path/is_windows/web.dart';

import 'platform_path.dart';
import 'unix_path.dart';
import 'windows_path.dart';
Expand Down
18 changes: 7 additions & 11 deletions lib/src/path/unix_path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ extension type UnixPath._(String string) implements Object {
/// {@endtemplate}
static const bool isIoSupported = io.isIoSupported;

static final RegExp _regularPathComponent = RegExp(r'^[ \\.\w-]+$');
static final RegExp _oneOrMoreSlashes = RegExp('$separator+');
static final p.Context _posix = p.Context(style: p.Style.posix);

Expand Down Expand Up @@ -48,7 +47,7 @@ extension type UnixPath._(String string) implements Object {
// trailing slash does not matter
if (string.endsWith(separator)) {
if (string.length == 1) {
yield RootDir(false);
yield const RootDir(false);
return;
}
removeLast = true;
Expand All @@ -65,20 +64,16 @@ extension type UnixPath._(String string) implements Object {
var current = iterator.current;
switch (current) {
case "":
yield RootDir(false);
yield const RootDir(false);
break;
case ".":
yield CurDir();
yield const CurDir();
break;
case "..":
yield ParentDir();
yield const ParentDir();
break;
default:
if (_regularPathComponent.hasMatch(current)) {
yield Normal(current);
} else {
yield Prefix(current);
}
yield Normal(current);
}
while (iterator.moveNext()) {
current = iterator.current;
Expand Down Expand Up @@ -254,8 +249,9 @@ extension type UnixPath._(String string) implements Object {
if (comps.length == 1) {
switch (comps.first) {
case RootDir():
case Prefix():
return None;
case Prefix():
unreachable("Prefixes are not possible for Unix");
case ParentDir():
case CurDir():
case Normal():
Expand Down
50 changes: 36 additions & 14 deletions lib/src/path/windows_path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:rust/rust.dart';
import 'io/io.dart' as io;
import 'utils.dart';


/// A Windows Path.
/// {@macro path.Path}
extension type WindowsPath._(String string) implements Object {
Expand Down Expand Up @@ -55,29 +54,32 @@ extension type WindowsPath._(String string) implements Object {
var current = iterator.current;
switch (current) {
case "":
yield RootDir(true);
yield const RootDir(true);
break;
case ".":
yield CurDir();
yield const CurDir();
break;
case "..":
yield ParentDir();
yield const ParentDir();
break;
default:
if (_regularPathComponent.hasMatch(current)) {
yield Normal(current);
} else {
yield Prefix(current);
if (string.replaceFirst(current, "").startsWith(separator)) {
yield const RootDir(true);
}
}
}
while (iterator.moveNext()) {
current = iterator.current;
switch (current) {
case ".":
yield CurDir();
yield const CurDir();
break;
case "..":
yield ParentDir();
yield const ParentDir();
break;
default:
yield Normal(current);
Expand Down Expand Up @@ -195,6 +197,12 @@ extension type WindowsPath._(String string) implements Object {
} else {
return None;
}
if (comps.length == 1) {
final prefix = comps[0];
if (prefix case Prefix(value: final prefix)) {
return None;
}
}
return Some(_joinComponents(comps));
}

Expand Down Expand Up @@ -268,15 +276,29 @@ WindowsPath _joinComponents(Iterable<Component> components) {
final buffer = StringBuffer();
final iterator = components.iterator;
forEachExceptFirstAndLast(iterator, doFirst: (e) {
if (e is RootDir) {
buffer.write(WindowsPath.separator);
} else {
buffer.write(e);
buffer.write(WindowsPath.separator);
switch (e) {
case Prefix():
buffer.write(e);
case RootDir():
buffer.write(WindowsPath.separator);
case CurDir():
case ParentDir():
case Normal():
buffer.write(e);
buffer.write(WindowsPath.separator);
}
}, doRest: (e) {
buffer.write(e);
buffer.write(WindowsPath.separator);
switch (e) {
case Prefix():
unreachable();
case RootDir():
buffer.write(WindowsPath.separator);
case CurDir():
case ParentDir():
case Normal():
buffer.write(e);
buffer.write(WindowsPath.separator);
}
}, doLast: (e) {
buffer.write(e);
}, doIfOnlyOne: (e) {
Expand All @@ -285,4 +307,4 @@ WindowsPath _joinComponents(Iterable<Component> components) {
return buffer.write("");
});
return WindowsPath(buffer.toString());
}
}
1 change: 0 additions & 1 deletion test/path/platform_vm_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import 'dart:io';

import 'package:rust/rust.dart';
import 'package:rust/src/path/io/unsupported.dart';
import 'package:test/expect.dart';
import 'package:test/scaffolding.dart';

Expand Down
76 changes: 58 additions & 18 deletions test/path/windows_path_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,44 @@ import 'package:test/expect.dart';
import 'package:test/scaffolding.dart';

void main() {
test("components", () {
var components = WindowsPath("C:\\foo\\bar\\..\\.\\bar").components().iterator;
components.moveNext();
expect(components.current, Prefix("C:"));
components.moveNext();
expect(components.current, RootDir(true));
components.moveNext();
expect(components.current, Normal("foo"));
components.moveNext();
expect(components.current, Normal("bar"));
components.moveNext();
expect(components.current, const ParentDir());
components.moveNext();
expect(components.current, const CurDir());
components.moveNext();
expect(components.current, Normal("bar"));
expect(components.moveNext(), false);

components = WindowsPath("C:\\").components().iterator;
components.moveNext();
expect(components.current, Prefix("C:"));
components.moveNext();
expect(components.current, RootDir(true));
expect(components.moveNext(), false);

components = WindowsPath("C:").components().iterator;
components.moveNext();
expect(components.current, Prefix("C:"));
expect(components.moveNext(), false);

components = WindowsPath("foo\\bar").components().iterator;
components.moveNext();
expect(components.current, Normal("foo"));
components.moveNext();
expect(components.current, Normal("bar"));
expect(components.moveNext(), false);
});

test("filePrefix", () {
expect(WindowsPath("foo.rs").filePrefix().unwrap(), "foo");
expect(WindowsPath("foo\\").filePrefix().unwrap(), "foo");
Expand All @@ -15,7 +53,8 @@ void main() {
expect(WindowsPath("").filePrefix().isNone(), true);

expect(
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
WindowsPath(
"\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.filePrefix()
.unwrap(),
"The Annual Report on the Health of the Parish of St");
Expand All @@ -32,7 +71,8 @@ void main() {
expect(WindowsPath("").fileStem().isNone(), true);

expect(
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
WindowsPath(
"\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.fileStem()
.unwrap(),
"The Annual Report on the Health of the Parish of St");
Expand All @@ -41,20 +81,20 @@ void main() {
test("parent", () {
expect(WindowsPath("temp\\foo.rs").parent().unwrap(), WindowsPath("temp"));
expect(WindowsPath("foo\\").parent().unwrap(), WindowsPath(""));
expect(WindowsPath("C:\\foo\\").parent().unwrap(), WindowsPath("C:"));
expect(WindowsPath("C:\\foo\\").parent().unwrap(), WindowsPath("C:\\"));
expect(WindowsPath(".foo").parent().unwrap(), WindowsPath(""));
expect(WindowsPath(".foo.rs").parent().unwrap(), WindowsPath(""));
expect(WindowsPath("foo").parent().unwrap(), WindowsPath(""));
expect(WindowsPath("foo.tar.gz").parent().unwrap(), WindowsPath(""));
expect(WindowsPath("temp\\foo.tar.gz").parent().unwrap(), WindowsPath("temp"));
expect(WindowsPath("temp1\\temp2\\foo.tar.gz").parent().unwrap(),
WindowsPath("temp1\\temp2"));
expect(WindowsPath("temp1\\temp2\\\\foo.tar.gz").parent().unwrap(),
WindowsPath("temp1\\temp2"));
expect(WindowsPath("temp1\\temp2\\foo.tar.gz").parent().unwrap(), WindowsPath("temp1\\temp2"));
expect(
WindowsPath("temp1\\temp2\\\\foo.tar.gz").parent().unwrap(), WindowsPath("temp1\\temp2"));
expect(WindowsPath("").parent().isNone(), true);

expect(
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
WindowsPath(
"\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.parent()
.unwrap(),
WindowsPath("\\Downloads"));
Expand All @@ -67,7 +107,7 @@ void main() {
ancestors.moveNext();
expect(ancestors.current, WindowsPath("C:\\foo"));
ancestors.moveNext();
expect(ancestors.current, WindowsPath("C:"));
expect(ancestors.current, WindowsPath("C:\\"));
expect(ancestors.moveNext(), false);

// Relative WindowsPaths should work similarly but without drive letters
Expand Down Expand Up @@ -121,27 +161,26 @@ void main() {
expect(WindowsPath("C:\\tmp\\foo.tar.gz").withExtension("tar.gz"),
WindowsPath("C:\\tmp\\foo.tar.tar.gz"));
expect(WindowsPath("tmp\\foo").withExtension("tar.gz"), WindowsPath("tmp\\foo.tar.gz"));
expect(WindowsPath("tmp\\.foo.tar").withExtension("tar.gz"),
WindowsPath("tmp\\.foo.tar.gz"));
expect(WindowsPath("tmp\\.foo.tar").withExtension("tar.gz"), WindowsPath("tmp\\.foo.tar.gz"));

expect(
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.withExtension(""),
WindowsPath(
"\\Downloads\\The Annual Report on the Health of the Parish of St"));
"\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.withExtension(""),
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St"));
});

test("withFileName", () {
expect(WindowsPath("foo").withFileName("bar"), WindowsPath("bar"));
expect(WindowsPath("foo.rs").withFileName("bar"), WindowsPath("bar"));
expect(WindowsPath("foo.tar.gz").withFileName("bar"), WindowsPath("bar"));
expect(
WindowsPath("C:\\tmp\\foo.tar.gz").withFileName("bar"), WindowsPath("C:\\tmp\\bar"));
expect(WindowsPath("C:\\tmp\\foo.tar.gz").withFileName("bar"), WindowsPath("C:\\tmp\\bar"));
expect(WindowsPath("tmp\\foo").withFileName("bar"), WindowsPath("tmp\\bar"));
expect(WindowsPath("C:\\var").withFileName("bar"), WindowsPath("C:\\bar"));

expect(
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
WindowsPath(
"\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.withFileName("dave"),
WindowsPath("\\Downloads\\dave"));
});
Expand All @@ -158,7 +197,8 @@ void main() {
expect(WindowsPath("\\..d").extension(), "d");

expect(
WindowsPath("\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
WindowsPath(
"\\Downloads\\The Annual Report on the Health of the Parish of St. Mary Abbotts, Kensington, during the year 1874")
.extension(),
" Mary Abbotts, Kensington, during the year 1874");
});
Expand Down

0 comments on commit 1080378

Please sign in to comment.