nushell/tests/plugins/call_decl.rs
Devyn Cairns f3843a6176
Make plugins able to find and call other commands (#13407)
# Description

Adds functionality to the plugin interface to support calling internal
commands from plugins. For example, using `view ir --json`:

```rust
let closure: Value = call.req(0)?;

let Some(decl_id) = engine.find_decl("view ir")? else {
    return Err(LabeledError::new("`view ir` not found"));
};

let ir_json = engine.call_decl(
    decl_id,
    EvaluatedCall::new(call.head)
        .with_named("json".into_spanned(call.head), Value::bool(true, call.head))
        .with_positional(closure),
    PipelineData::Empty,
    true,
    false,
)?.into_value()?.into_string()?;

let ir = serde_json::from_value(&ir_json);

// ...
```

# User-Facing Changes

Plugin developers can now use `EngineInterface::find_decl()` and
`call_decl()` to call internal commands, which could be handy for
formatters like `to csv` or `to nuon`, or for reflection commands that
help gain insight into the engine.

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
- [ ] release notes
- [ ] update plugin protocol documentation: `FindDecl`, `CallDecl`
engine calls; `Identifier` engine call response
2024-07-19 13:54:21 +08:00

42 lines
1 KiB
Rust

use nu_test_support::nu_with_plugins;
#[test]
fn call_to_json() {
let result = nu_with_plugins!(
cwd: ".",
plugin: ("nu_plugin_example"),
r#"
[42] | example call-decl 'to json' {indent: 4}
"#
);
assert!(result.status.success());
// newlines are removed from test output
assert_eq!("[ 42]", result.out);
}
#[test]
fn call_reduce() {
let result = nu_with_plugins!(
cwd: ".",
plugin: ("nu_plugin_example"),
r#"
[1 2 3] | example call-decl 'reduce' {fold: 10} { |it, acc| $it + $acc }
"#
);
assert!(result.status.success());
assert_eq!("16", result.out);
}
#[test]
fn call_scope_variables() {
let result = nu_with_plugins!(
cwd: ".",
plugin: ("nu_plugin_example"),
r#"
let test_var = 10
example call-decl 'scope variables' | where name == '$test_var' | length
"#
);
assert!(result.status.success());
assert_eq!("1", result.out);
}