nushell/crates/nu-protocol/tests/test_config.rs
Eric Hodel 7071617f18
Allow plugins to receive configuration from the nushell configuration (#10955)
# Description

When nushell calls a plugin it now sends a configuration `Value` from
the nushell config under `$env.config.plugins.PLUGIN_SHORT_NAME`. This
allows plugin authors to read configuration provided by plugin users.

The `PLUGIN_SHORT_NAME` must match the registered filename after
`nu_plugin_`. If you register `target/debug/nu_plugin_config` the
`PLUGIN_NAME` will be `config` and the nushell config will loook like:

        $env.config = {
          # ...
          plugins: {
            config: [
              some
              values
            ]
          }
        }

Configuration may also use a closure which allows passing values from
`$env` to a plugin:

        $env.config = {
          # ...
          plugins: {
            config: {||
              $env.some_value
            }
          }
        }

This is a breaking change for the plugin API as the `Plugin::run()`
function now accepts a new configuration argument which is an
`&Option<Value>`. If no configuration was supplied the value is `None`.

Plugins compiled after this change should work with older nushell, and
will behave as if the configuration was not set.

Initially discussed in #10867

# User-Facing Changes

* Plugins can read configuration data stored in `$env.config.plugins`
* The plugin `CallInfo` now includes a `config` entry, existing plugins
will require updates

# Tests + Formatting

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting

- [ ] Update [Creating a plugin (in
Rust)](https://www.nushell.sh/contributor-book/plugins.html#creating-a-plugin-in-rust)
[source](https://github.com/nushell/nushell.github.io/blob/main/contributor-book/plugins.md)
- [ ] Add "Configuration" section to [Plugins
documentation](https://www.nushell.sh/contributor-book/plugins.html)
2024-01-15 16:59:47 +08:00

112 lines
3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use nu_test_support::{nu, nu_repl_code};
#[test]
fn filesize_metric_true() {
let code = &[
r#"$env.config = { filesize: { metric: true, format:"mb" } }"#,
r#"20mib | into string"#,
];
let actual = nu!(nu_repl_code(code));
assert_eq!(actual.out, "21.0 MB");
}
#[test]
fn filesize_metric_false() {
let code = &[
r#"$env.config = { filesize: { metric: false, format:"mib" } }"#,
r#"20mib | into string"#,
];
let actual = nu!(nu_repl_code(code));
assert_eq!(actual.out, "20.0 MiB");
}
#[test]
fn filesize_metric_overrides_format() {
let code = &[
r#"$env.config = { filesize: { metric: false, format:"mb" } }"#,
r#"20mib | into string"#,
];
let actual = nu!(nu_repl_code(code));
assert_eq!(actual.out, "20.0 MiB");
}
#[test]
fn filesize_format_auto_metric_true() {
let code = &[
r#"$env.config = { filesize: { metric: true, format:"auto" } }"#,
r#"[2mb 2gb 2tb] | into string | to nuon"#,
];
let actual = nu!(nu_repl_code(code));
assert_eq!(actual.out, r#"["2.0 MB", "2.0 GB", "2.0 TB"]"#);
}
#[test]
fn filesize_format_auto_metric_false() {
let code = &[
r#"$env.config = { filesize: { metric: false, format:"auto" } }"#,
r#"[2mb 2gb 2tb] | into string | to nuon"#,
];
let actual = nu!(nu_repl_code(code));
assert_eq!(actual.out, r#"["1.9 MiB", "1.9 GiB", "1.8 TiB"]"#);
}
#[test]
fn fancy_default_errors() {
let actual = nu!(nu_repl_code(&[
r#"def force_error [x] {
error make {
msg: "oh no!"
label: {
text: "here's the error"
span: (metadata $x).span
}
}
}"#,
r#"force_error "My error""#
]));
assert_eq!(
actual.err,
"Error: \u{1b}[31m×\u{1b}[0m oh no!\n ╭─[\u{1b}[36;1;4mline1\u{1b}[0m:1:1]\n \u{1b}[2m1\u{1b}[0m │ force_error \"My error\"\n · \u{1b}[35;1m ─────┬────\u{1b}[0m\n · \u{1b}[35;1m╰── \u{1b}[35;1mhere's the error\u{1b}[0m\u{1b}[0m\n ╰────\n\n\n"
);
}
#[test]
fn narratable_errors() {
let actual = nu!(nu_repl_code(&[
r#"$env.config = { error_style: "plain" }"#,
r#"def force_error [x] {
error make {
msg: "oh no!"
label: {
text: "here's the error"
span: (metadata $x).span
}
}
}"#,
r#"force_error "my error""#,
]));
assert_eq!(
actual.err,
r#"Error: oh no!
Diagnostic severity: error
Begin snippet for line2 starting at line 1, column 1
snippet line 1: force_error "my error"
label at line 1, columns 13 to 22: here's the error
"#,
);
}
#[test]
fn plugins() {
let code = &[
r#"$env.config = { plugins: { nu_plugin_config: { key: value } } }"#,
r#"$env.config.plugins"#,
];
let actual = nu!(nu_repl_code(code));
assert_eq!(actual.out, r#"{nu_plugin_config: {key: value}}"#);
}