Charlotte Meyer
5e18e89af4
This adds basic addition, substraction, multiplication, and division commands as builtins. All of those operate solely on f64's. Signed-off-by: Charlotte Meyer <dev@buffet.sh>
175 lines
3.5 KiB
Rust
175 lines
3.5 KiB
Rust
use expect_test::{expect, Expect};
|
|
use oyster_parser::ast;
|
|
use oyster_runtime::Shell;
|
|
|
|
use crate::collect_output;
|
|
|
|
fn check(ast: &ast::Code, expect: Expect) {
|
|
let actual = collect_output(|| {
|
|
let mut shell = Shell::new().unwrap();
|
|
shell.builtins_mut().add_defaults();
|
|
shell.run(ast).unwrap();
|
|
});
|
|
expect.assert_debug_eq(&actual);
|
|
}
|
|
|
|
#[test]
|
|
fn add_single() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("+")]),
|
|
Word(vec![WordPart::Text("5")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"5\r\n"
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn add_multiple() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("+")]),
|
|
Word(vec![WordPart::Text("5")]),
|
|
Word(vec![WordPart::Text("2")]),
|
|
Word(vec![WordPart::Text("3")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"10\r\n"
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sub() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("-")]),
|
|
Word(vec![WordPart::Text("5")]),
|
|
Word(vec![WordPart::Text("2")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"3\r\n"
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn mul() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("*")]),
|
|
Word(vec![WordPart::Text("5")]),
|
|
Word(vec![WordPart::Text("2")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"10\r\n"
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn simple_div() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("/")]),
|
|
Word(vec![WordPart::Text("10")]),
|
|
Word(vec![WordPart::Text("2")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"5\r\n"
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn fraction_div() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("/")]),
|
|
Word(vec![WordPart::Text("9")]),
|
|
Word(vec![WordPart::Text("2")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"4.5\r\n"
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn div_inf() {
|
|
let ast = {
|
|
use oyster_parser::ast::*;
|
|
|
|
Code(vec![Statement::Pipeline(Pipeline(vec![Command(
|
|
vec![
|
|
Word(vec![WordPart::Text("/")]),
|
|
Word(vec![WordPart::Text("1")]),
|
|
Word(vec![WordPart::Text("0")]),
|
|
],
|
|
Redirect::None,
|
|
)]))])
|
|
};
|
|
|
|
check(
|
|
&ast,
|
|
expect![[r#"
|
|
"inf\r\n"
|
|
"#]],
|
|
);
|
|
}
|