nu_plugin_test_support/
lib.rs

1//! Test support for [Nushell](https://nushell.sh) plugins.
2//!
3//! # Example
4//!
5//! ```rust
6//! use std::sync::Arc;
7//!
8//! use nu_plugin::*;
9//! use nu_plugin_test_support::PluginTest;
10//! use nu_protocol::{
11//!     Example, IntoInterruptiblePipelineData, LabeledError, PipelineData, ShellError, Signals,
12//!     Signature, Span, Type, Value,
13//! };
14//!
15//! struct LowercasePlugin;
16//! struct Lowercase;
17//!
18//! impl PluginCommand for Lowercase {
19//!     type Plugin = LowercasePlugin;
20//!
21//!     fn name(&self) -> &str {
22//!         "lowercase"
23//!     }
24//!
25//!     fn description(&self) -> &str {
26//!         "Convert each string in a stream to lowercase"
27//!     }
28//!
29//!     fn signature(&self) -> Signature {
30//!         Signature::build(self.name()).input_output_type(
31//!             Type::List(Type::String.into()),
32//!             Type::List(Type::String.into()),
33//!         )
34//!     }
35//!
36//!     fn examples(&self) -> Vec<Example> {
37//!         vec![Example {
38//!             example: r#"[Hello wORLD] | lowercase"#,
39//!             description: "Lowercase a list of strings",
40//!             result: Some(Value::test_list(vec![
41//!                 Value::test_string("hello"),
42//!                 Value::test_string("world"),
43//!             ])),
44//!         }]
45//!     }
46//!
47//!     fn run(
48//!         &self,
49//!         _plugin: &LowercasePlugin,
50//!         _engine: &EngineInterface,
51//!         call: &EvaluatedCall,
52//!         input: PipelineData,
53//!     ) -> Result<PipelineData, LabeledError> {
54//!         let span = call.head;
55//!         Ok(input.map(
56//!             move |value| {
57//!                 value
58//!                     .as_str()
59//!                     .map(|string| Value::string(string.to_lowercase(), span))
60//!                     // Errors in a stream should be returned as values.
61//!                     .unwrap_or_else(|err| Value::error(err, span))
62//!             },
63//!             &Signals::empty(),
64//!         )?)
65//!     }
66//! }
67//!
68//! impl Plugin for LowercasePlugin {
69//!     fn version(&self) -> String {
70//!         env!("CARGO_PKG_VERSION").into()
71//!     }
72//!
73//!     fn commands(&self) -> Vec<Box<dyn PluginCommand<Plugin=Self>>> {
74//!         vec![Box::new(Lowercase)]
75//!     }
76//! }
77//!
78//! // #[test]
79//! fn test_examples() -> Result<(), ShellError> {
80//!     PluginTest::new("lowercase", LowercasePlugin.into())?
81//!         .test_command_examples(&Lowercase)
82//! }
83//!
84//! // #[test]
85//! fn test_lowercase() -> Result<(), ShellError> {
86//!     let input = vec![Value::test_string("FooBar")].into_pipeline_data(Span::test_data(), Signals::empty());
87//!     let output = PluginTest::new("lowercase", LowercasePlugin.into())?
88//!         .eval_with("lowercase", input)?
89//!         .into_value(Span::test_data())?;
90//!
91//!     assert_eq!(
92//!         Value::test_list(vec![
93//!             Value::test_string("foobar")
94//!         ]),
95//!         output
96//!     );
97//!     Ok(())
98//! }
99//! #
100//! # test_examples().unwrap();
101//! # test_lowercase().unwrap();
102//! ```
103
104mod diff;
105mod fake_persistent_plugin;
106mod fake_register;
107mod plugin_test;
108mod spawn_fake_plugin;
109
110pub use plugin_test::PluginTest;