new command url parse (#6854) and url subcommands tests#7124
new command url parse (#6854) and url subcommands tests#7124rgwood merged 1 commit intonushell:mainfrom
url parse (#6854) and url subcommands tests#7124Conversation
| } | ||
|
|
||
| fn signature(&self) -> Signature { | ||
| Signature::build("url parse") |
There was a problem hiding this comment.
You'll need to declare a vec of (input_type, output_type) pairs here -- lots of examples in the other command files. You'll see the test fail for your example until you declare these:
thread 'network::url::parse::test::test_examples' panicked at 'The example `echo 'http://www.example.com/foo/bar?p=section&s=&f[name]=vldc' | url parse` demonstrates a transformation of type String -> Record([("scheme", String), ("host", String), ("path", String), ("query", String), ("params", Record([("p", String), ("s", String), ("f[name]", String)]))]). However, this does not match the declared signature: []. (Did you forget to declare the input and output types for the command?) For this command, `vectorizes_over_list` is false and `operates_on_cell_paths()` is true.', crates/nu-command/src/example_test.rs:178:21
| } | ||
|
|
||
| fn search_terms(&self) -> Vec<&str> { | ||
| vec!["url", "parse"] |
There was a problem hiding this comment.
I believe that we don't add any words from the command name itself to the search terms: just any related terms that you believe users might enter when looking for this.
There was a problem hiding this comment.
hmm thanks for the explanation, so maybe "scheme", "hostname", "port", "path", and "parameters" ? That it's what the command returns
| fn examples(&self) -> Vec<Example> { | ||
| vec![Example { | ||
| description: "Parses a url", | ||
| example: "echo 'http://www.example.com/foo/bar?p=section&s=&f[name]=vldc' | url parse", |
There was a problem hiding this comment.
Although several commands still do it in their examples, echo isn't necessary any longer and for cases like this IMO we should omit the echo: a data structure can just be supplied as input to a pipeline.
| span: head, | ||
| }); | ||
| } | ||
| } |
There was a problem hiding this comment.
What do you think about writing this something like the following?
vals.push(Value::String {
val: url.port().map(|p| p.to_string()).unwrap_or("".into()),
span: head,
});There was a problem hiding this comment.
thanks that's much better :) I am new to Rust, I still don't know the best way to handle some things.
I'll change to your code in next commit.
| for (k, v) in result { | ||
| param_cols.push(k); | ||
| param_vals.push(Value::String { val: v, span: head }) | ||
| } |
There was a problem hiding this comment.
What do you think about writing this something like this?
let (param_cols, param_vals) = result
.into_iter()
.map(|(k, v)| (k, Value::String { val: v, span: head }))
.unzip();| } | ||
| Err(_e) => { | ||
| return Err(ShellError::UnsupportedInput( | ||
| "Incomplete or incorrect URL. Expected a full Url, e.g., https://www.example.com" |
There was a problem hiding this comment.
Inconsistent capitalization in error message. (It's nice to have our error messages perfect!)
|
There are some clippy failures to be fixed before the CI will run the tests. |
|
Thanks so much for doing this -- it's a really nicely executed PR with great tests and documentation. There are some related design issues, which I'm just going to list, but sorting all this out is probably a separate issue.
|
| @@ -0,0 +1,28 @@ | |||
| use nu_test_support::{nu, pipeline}; | |||
There was a problem hiding this comment.
Do you think we should keep url path and url query and url scheme? My immediate reaction is that they should not exist if we have url parse since one should just do e.g. ($url | url parse).path.
cd20001 to
4d341fb
Compare
| "port".to_string(), | ||
| "path".to_string(), | ||
| "query".to_string(), | ||
| "params".to_string(), |
There was a problem hiding this comment.
Any interest in adding the other parsed components while you're at it? I think username and password are pretty useful for people working with ssh, and fragment is common... may as well take them all?
| Value::String { | ||
| val: url | ||
| .port() | ||
| .map(|p| p.to_string()) |
There was a problem hiding this comment.
I believe we should leave this as an integer seeing as Rust is providing it as an int.
There was a problem hiding this comment.
in that case, what should be the output when there's no port on url ? An empty string? I could do something like this for port value:
match url.port() {
Some(p) => Value::Int {
val: p as i64,
span: head,
},
None => Value::String {
val: "".into(),
span: head,
}
},
But this way, the url parse output type for port will be string or int depending on input.
There was a problem hiding this comment.
Oh you're right, sorry, I think what I said doesn't make sense until/unless Nushell gains an Option type in the future. As you have it is the way for now.
|
Would you be able to delete all the commands that this supersedes please? Then this is looking great and ready to merge (just a couple of review comments)! |
27f3d68 to
71b2c57
Compare
|
This looks beautiful to me. Very clean, and more functionality than before. And well tested. LGTM! |
| "╭──────────┬───────────────────╮\ | ||
| │ scheme │ https │\ | ||
| │ username │ │\ | ||
| │ password │ │\ | ||
| │ host │ www.abc.com │\ | ||
| │ port │ │\ | ||
| │ path │ / │\ | ||
| │ query │ │\ | ||
| │ fragment │ │\ | ||
| │ params │ {record 0 fields} │\ | ||
| ╰──────────┴───────────────────╯" |
There was a problem hiding this comment.
I think that we generally want to avoid testing the formatted output from table like this. Tests like this are fragile and will break whenever we tweak Nu's display logic.
Alternative approaches:
- Figure out a way to test equality against a
Value::Record(instead of text output) in Rust - Do the equality check against a Nu record in Nu code. Something like:
let actual = nu!(
cwd: ".", pipeline(
r#"
("https://www.abc.com" | url parse) == {scheme: 'https', username: '', ...}
"#
));
assert_eq!(actual.out, "true");(there's probably a better way than that, it's just the first thing that came to mind)
There was a problem hiding this comment.
that makes sense, I just copied how some other tests were done. I can change the tests, just waiting for confirmation
|
Agreed with Dan, this looks great. Thank you for the contribution! I just have one concern about the tests, let me know what you think. |
d60cb8d to
a186826
Compare
*code refactor from PR tips & clippy fixes *added username, password, and fragment *commands `url host`, `url scheme`, `url query`, and `url path` removed *tests refactoring - avoid formatted output
4d3b126 to
608c87e
Compare
fdncred
left a comment
There was a problem hiding this comment.
I'm really loving this cleanup, code-work, tests, and general usability improvements. This is exactly the type of PR that we need more of. Good work! I'm ready to land.
|
Fantastic change, thanks. Because this is a breaking change (existing commands removed), could you please document it in the blog post for v0.72 when you have time? nushell/nushell.github.io#666 |
Description
New command

url parse, and added some tests to commandsurl host,url scheme,url path,url query.Fixes #6854
Tests + Formatting
Commands with error:
"" | url parse"aaaa" | url parseValid commands:
"http://www.abc.com/11/22?param1=ab¶m2=zz" | url parse"http://www.abc.com:8081/11/22?param1=ab¶m2=zz" | url parseUser-Facing Changes
New command
url parse.