mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(resolver): complete query and fragment parsing (#579)
This commit is contained in:
parent
30b9731843
commit
fa20844802
3 changed files with 62 additions and 14 deletions
|
|
@ -51,7 +51,7 @@ Tests ported from [enhanced-resolve](https://github.com/webpack/enhanced-resolve
|
|||
- ~[ ] forEachBail.test.js~
|
||||
- [ ] fullSpecified.test.js
|
||||
- [ ] getPaths.test.js
|
||||
- [ ] identifier.test.js
|
||||
- [x] identifier.test.js (see unit test in `crates/oxc_resolver/src/request.rs`)
|
||||
- [ ] importsField.test.js
|
||||
- [x] incorrect-description-file.test.js (need to add ctx.fileDependencies)
|
||||
- [ ] missing.test.js
|
||||
|
|
|
|||
|
|
@ -63,20 +63,20 @@ impl<'a> Request<'a> {
|
|||
let mut fragment_start: Option<usize> = None;
|
||||
|
||||
for (i, c) in request.as_bytes().iter().enumerate().skip(skip) {
|
||||
match *c {
|
||||
b'?' => query_start = Some(i),
|
||||
b'#' => fragment_start = Some(i),
|
||||
_ => {}
|
||||
if *c == b'?' {
|
||||
query_start = Some(i);
|
||||
}
|
||||
if *c == b'#' {
|
||||
fragment_start = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
match (query_start, fragment_start) {
|
||||
(Some(i), Some(j)) if i < j => {
|
||||
(Some(i), Some(j)) => {
|
||||
debug_assert!(i < j);
|
||||
(&request[..i], Some(&request[i..j]), Some(&request[j..]))
|
||||
}
|
||||
(Some(i), Some(j)) if i > j => {
|
||||
(&request[..j], Some(&request[i..]), Some(&request[j..i]))
|
||||
}
|
||||
(Some(i), None) => (&request[..i], Some(&request[i..]), None),
|
||||
(None, Some(j)) => (&request[..j], None, Some(&request[j..])),
|
||||
_ => (request, None, None),
|
||||
|
|
@ -112,7 +112,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn relative() -> Result<(), RequestError> {
|
||||
let requests = ["./test", "../test?#", "../../test?#"];
|
||||
let requests = ["./test", "../test", "../../test"];
|
||||
for request in requests {
|
||||
let mut r = request.to_string();
|
||||
r.push_str("?#");
|
||||
|
|
@ -163,8 +163,8 @@ mod tests {
|
|||
("a?#fragment", Some("?"), Some("#fragment")),
|
||||
("a?query#", Some("?query"), Some("#")),
|
||||
("a?query#fragment", Some("?query"), Some("#fragment")),
|
||||
("a#fragment?", Some("?"), Some("#fragment")),
|
||||
("a#fragment?query", Some("?query"), Some("#fragment")),
|
||||
("a#fragment?", None, Some("#fragment?")),
|
||||
("a#fragment?query", None, Some("#fragment?query")),
|
||||
];
|
||||
|
||||
for (request_str, query, fragment) in data {
|
||||
|
|
@ -176,4 +176,52 @@ mod tests {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
// https://github.com/webpack/enhanced-resolve/blob/main/test/identifier.test.js
|
||||
fn enhanced_resolve_edge_cases() -> Result<(), RequestError> {
|
||||
let data = [
|
||||
("path/#", "path/", "", "#"),
|
||||
("path/as/?", "path/as/", "?", ""),
|
||||
("path/#/?", "path/", "", "#/?"),
|
||||
("path/#repo#hash", "path/", "", "#repo#hash"),
|
||||
("path/#r#hash", "path/", "", "#r#hash"),
|
||||
("path/#repo/#repo2#hash", "path/", "", "#repo/#repo2#hash"),
|
||||
("path/#r/#r#hash", "path/", "", "#r/#r#hash"),
|
||||
("path/#/not/a/hash?not-a-query", "path/", "", "#/not/a/hash?not-a-query"),
|
||||
];
|
||||
|
||||
for (request_str, path, query, fragment) in data {
|
||||
let request = Request::parse(request_str)?;
|
||||
assert_eq!(request.path.as_str(), path, "{request_str}");
|
||||
assert_eq!(request.query.unwrap_or(""), query, "{request_str}");
|
||||
assert_eq!(request.fragment.unwrap_or(""), fragment, "{request_str}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://github.com/webpack/enhanced-resolve/blob/main/test/identifier.test.js
|
||||
#[test]
|
||||
fn enhanced_resolve_windows_like() -> Result<(), RequestError> {
|
||||
let data = [
|
||||
("path\\#", "path\\", "", "#"),
|
||||
("path\\as\\?", "path\\as\\", "?", ""),
|
||||
("path\\#\\?", "path\\", "", "#\\?"),
|
||||
("path\\#repo#hash", "path\\", "", "#repo#hash"),
|
||||
("path\\#r#hash", "path\\", "", "#r#hash"),
|
||||
("path\\#repo\\#repo2#hash", "path\\", "", "#repo\\#repo2#hash"),
|
||||
("path\\#r\\#r#hash", "path\\", "", "#r\\#r#hash"),
|
||||
("path\\#/not/a/hash?not-a-query", "path\\", "", "#/not/a/hash?not-a-query"),
|
||||
];
|
||||
|
||||
for (request_str, path, query, fragment) in data {
|
||||
let request = Request::parse(request_str)?;
|
||||
assert_eq!(request.path.as_str(), path, "{request_str}");
|
||||
assert_eq!(request.query.unwrap_or(""), query, "{request_str}");
|
||||
assert_eq!(request.fragment.unwrap_or(""), fragment, "{request_str}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ fn resolve() {
|
|||
("from nested directory to not overwritten file in module", f.join("multiple_modules"), "m1/b.js", f.join("node_modules/m1/b.js")),
|
||||
("file with query", f.clone(), "./main1.js?query", f.join("main1.js?query")),
|
||||
("file with fragment", f.clone(), "./main1.js#fragment", f.join("main1.js#fragment")),
|
||||
("file with fragment and query", f.clone(), "./main1.js#fragment?query", f.join("main1.js?query#fragment")),
|
||||
("file with fragment and query", f.clone(), "./main1.js#fragment?query", f.join("main1.js#fragment?query")),
|
||||
("file with query and fragment", f.clone(), "./main1.js?#fragment", f.join("main1.js?#fragment")),
|
||||
("file in module with query", f.clone(), "m1/a?query", f.join("node_modules/m1/a.js?query")),
|
||||
("file in module with fragment", f.clone(), "m1/a#fragment", f.join("node_modules/m1/a.js#fragment")),
|
||||
("file in module with fragment and query", f.clone(), "m1/a#fragment?query", f.join("node_modules/m1/a.js?query#fragment")),
|
||||
("file in module with fragment and query", f.clone(), "m1/a#fragment?query", f.join("node_modules/m1/a.js#fragment?query")),
|
||||
("file in module with query and fragment", f.clone(), "m1/a?#fragment", f.join("node_modules/m1/a.js?#fragment")),
|
||||
("file in module with query and fragment", f.clone(), "m1/a?#fragment", f.join("node_modules/m1/a.js?#fragment")),
|
||||
("differ between directory and file, resolve file", f.clone(), "./dirOrFile", f.join("dirOrFile.js")),
|
||||
|
|
|
|||
Loading…
Reference in a new issue