Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shell: Usability fixes and test #102

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
Loading