Skip to content

Commit

Permalink
Shell: Usability fixes and test
Browse files Browse the repository at this point in the history
Merges: #102
  • Loading branch information
chrysn authored Aug 20, 2024
2 parents 7b3aec0 + f352dfb commit d616954
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub trait CommandList<const BUFSIZE: usize = { riot_sys::SHELL_DEFAULT_BUFSIZE a
/// The handler will be called every time the command is entered, and is passed the arguments
/// including its own name in the form of [Args]. Currently, RIOT ignores the return value of
/// the function.
fn and<'a, H, T>(self, name: &'a CStr, desc: &'a CStr, handler: H) -> Command<'a, Self, H, T>
fn and<'a, H, T>(self, name: &'a CStr, desc: &'a CStr, handler: H) -> impl CommandList<BUFSIZE>
where
H: FnMut(&mut stdio::Stdio, Args<'_>) -> T,
T: crate::main::Termination,
Expand Down
15 changes: 15 additions & 0 deletions tests/shell/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "riot-wrappers-test-shell"
version = "0.1.0"
authors = ["Christian Amsüss <[email protected]>"]
edition = "2021"
publish = false

[lib]
crate-type = ["staticlib"]

[profile.release]
panic = "abort"

[dependencies]
riot-wrappers = { path = "../..", features = [ "set_panic_handler", "panic_handler_format" ] }
10 changes: 10 additions & 0 deletions tests/shell/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# name of your application
APPLICATION = riot-wrappers-test-shell
BOARD ?= native
APPLICATION_RUST_MODULE = riot_wrappers_test_shell
BASELIBS += $(APPLICATION_RUST_MODULE).module
FEATURES_REQUIRED += rust_target

USEMODULE += shell

include $(RIOTBASE)/Makefile.include
40 changes: 40 additions & 0 deletions tests/shell/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![no_std]

use core::fmt::Write;
use riot_wrappers::println;
use riot_wrappers::riot_main;
use riot_wrappers::shell::CommandList;

riot_main!(main);

fn main() -> ! {
let mut nonglobal_state = 0;

// Not running anything fancy with run_once (where we could, for example, play around with
// different buffer sizes) because .

riot_wrappers::shell::new()
.and(
c"closure",
c"Run a command that holds a mutable reference",
|stdout, _args| {
writeln!(stdout, "Previous state was {}", nonglobal_state).unwrap();
nonglobal_state += 1;
writeln!(stdout, "New state is {}", nonglobal_state).unwrap();
},
)
.run_forever()
}

fn do_echo(_stdio: &mut riot_wrappers::stdio::Stdio, args: riot_wrappers::shell::Args<'_>) {
println!("Arguments:");
for a in args.iter() {
println!("- {}", a);
}
}
riot_wrappers::static_command!(
echo,
"echo",
"Print the arguments in separate lines",
do_echo
);
32 changes: 32 additions & 0 deletions tests/shell/tests/01-run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python3

import sys
from testrunner import run

def test(child):
child.expect("> ")
child.sendline("help")
# Could also be the other sequence, we're not guaranteeing that
commands = ["closure", "echo"]
helps = ["Run a command that holds a mutable reference", "Print the arguments in separate lines"]
command1 = child.expect(commands)
help1 = child.expect(helps)
command2 = child.expect(commands)
help2 = child.expect(helps)
if command1 != help1 or command2 != help2:
print("Commands and helps were mixed up")
sys.exit(1)
child.expect("> ")
child.sendline("echo foo bar")
child.expect("- echo")
child.expect("- foo")
child.expect("- bar")
child.expect("> ")
child.sendline("closure")
child.expect("New state is 1")
child.expect("> ")
child.sendline("closure")
child.expect("New state is 2")

if __name__ == "__main__":
sys.exit(run(test))

0 comments on commit d616954

Please sign in to comment.