use crate::args::{ArgSpec, ArgVec};
use crate::err::Error;
use crate::libapi::FuncDef;
use crate::str::Buf;
use crate::val::{Val, ValDef};
const PLAIN: FuncDef = func! {
resynth fn PLAIN(
a: U64,
b: Str,
=>
c: U64 = 123,
d: Str = b"hello",
e: Type = ValType::Bool,
=>
Void
) -> Void
|_args| {
Ok(Val::Nil)
}
};
#[test]
fn argvec_simple() {
let args = vec![ArgSpec::from(1), ArgSpec::from(b"pos")];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(
Val::U64(1),
Val::str(b"pos"),
Val::U64(123),
Val::str(b"hello"),
Val::Nil,
),
vec!(),
)),
PLAIN.argvec(None, args)
)
}
#[test]
fn argvec_nullable() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(b"pos"),
ArgSpec::from(("e", true)),
];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(
Val::U64(1),
Val::str(Buf::from(b"pos")),
Val::U64(123),
Val::str(b"hello"),
Val::Bool(true),
),
vec!(),
)),
PLAIN.argvec(None, args)
)
}
#[test]
fn argvec_type_mismatch_1() {
let args = vec![ArgSpec::from(1), ArgSpec::from(true)];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args))
}
#[test]
fn argvec_type_mismatch_2() {
let args = vec![ArgSpec::from(1), ArgSpec::from(("b", ValDef::Bool(true)))];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args))
}
#[test]
fn argvec_type_mismatch_3() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(b"hello"),
ArgSpec::from(("c", ValDef::U64(3))),
ArgSpec::from(("d", ValDef::Bool(true))),
];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args))
}
#[test]
fn argvec_named_positionals() {
let args = vec![
ArgSpec::from(("a", ValDef::U64(0))),
ArgSpec::from(("b", ValDef::Str(b"goodbye"))),
];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(
Val::U64(0),
Val::str(b"goodbye"),
Val::U64(123),
Val::str(b"hello"),
Val::Nil,
),
vec!()
)),
PLAIN.argvec(None, args),
)
}
#[test]
fn argvec_too_many_positionals() {
let args = vec![ArgSpec::from(1), ArgSpec::from(b"pos"), ArgSpec::from(2)];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(
Val::U64(1),
Val::str(b"pos"),
Val::U64(2),
Val::str(b"hello"),
Val::Nil,
),
vec!()
)),
PLAIN.argvec(None, args),
)
}
#[test]
fn argvec_not_enough_args() {
let args = vec![ArgSpec::from(1)];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args),)
}
#[test]
fn argvec_multiple_positional() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(b"hello"),
ArgSpec::from(("a", ValDef::U64(2))),
];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args),)
}
#[test]
fn argvec_multiple_optional() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(b"hello"),
ArgSpec::from(111),
ArgSpec::from(("c", ValDef::U64(222))),
];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args),)
}
#[test]
fn argvec_multiple_named_optional() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(b"hello"),
ArgSpec::from(("c", ValDef::U64(111))),
ArgSpec::from(("c", ValDef::U64(222))),
];
assert_eq!(Err(Error::TypeError), PLAIN.argvec(None, args),)
}
const COLLECT: FuncDef = func! {
resynth fn COLLECT(
a: U64,
=>
b: U64 = 123,
=>
Str
) -> Void
|_args| {
Ok(Val::Nil)
}
};
#[test]
fn collect_none() {
let args = vec![ArgSpec::from(1), ArgSpec::from(("b", ValDef::U64(234)))];
assert_eq!(
Ok(ArgVec::new(None, vec!(Val::U64(1), Val::U64(234),), vec!())),
COLLECT.argvec(None, args),
)
}
#[test]
fn collect_with_named() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(("b", ValDef::U64(234))),
ArgSpec::from(b"hello"),
ArgSpec::from(b"world"),
];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(Val::U64(1), Val::U64(234),),
vec!(Val::str(b"hello"), Val::str(b"world"),),
)),
COLLECT.argvec(None, args),
)
}
#[test]
fn collect_with_defaults() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(b"hello"),
ArgSpec::from(b"world"),
];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(Val::U64(1), Val::U64(123),),
vec!(Val::str(b"hello"), Val::str(b"world"),),
)),
COLLECT.argvec(None, args),
)
}
#[test]
fn collect_bad_type() {
let args = vec![
ArgSpec::from(1),
ArgSpec::from(("b", ValDef::U64(234))),
ArgSpec::from(b"hello"),
ArgSpec::from(true),
];
assert_eq!(Err(Error::TypeError), COLLECT.argvec(None, args),)
}
const EMPTY: FuncDef = func! {
resynth fn EMPTY(
=>
=>
Str
) -> Void
|_args| {
Ok(Val::Nil)
}
};
#[test]
fn argvec_empty() {
let args = vec![];
assert_eq!(
Ok(ArgVec::new(None, vec!(), vec!(),)),
EMPTY.argvec(None, args)
)
}
#[test]
fn argvec_empty_extra() {
let args = vec![ArgSpec::from(b"hello"), ArgSpec::from(b"world")];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(),
vec!(Val::str(b"hello"), Val::str(b"world"),),
)),
EMPTY.argvec(None, args)
)
}
const NAMED: FuncDef = func! {
resynth fn NAMED(
=>
a: U64 = 123,
b: Str = b"hello",
c: Bool = true,
=>
Void
) -> Void
|_args| {
Ok(Val::Nil)
}
};
#[test]
fn argvec_optional_anonymous() {
let args = vec![ArgSpec::from(1u64), ArgSpec::from(b"supplied")];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(Val::U64(1), Val::str(b"supplied"), Val::Bool(true),),
vec!(),
)),
NAMED.argvec(None, args)
)
}
const OPTIONAL_COLLECT_STR: FuncDef = func! {
resynth fn OPTIONAL_COLLECT_STR(
=>
a: Bool = true,
b: U64 = 123,
c: Str = b"hello",
=>
Str
) -> Void
|_args| {
Ok(Val::Nil)
}
};
#[test]
fn argvec_optional_collect_str() {
let args = vec![ArgSpec::from(1u64), ArgSpec::from(b"supplied")];
assert_eq!(
Ok(ArgVec::new(
None,
vec!(Val::Bool(true), Val::U64(123), Val::str(b"hello"),),
vec!(Val::U64(1), Val::str(b"supplied"),),
)),
OPTIONAL_COLLECT_STR.argvec(None, args)
)
}
const OPTIONAL_COLLECT_U64: FuncDef = func! {
resynth fn OPTIONAL_COLLECT_U64(
=>
a: U64 = 123,
b: Str = b"hello",
c: Bool = true,
=>
U64
) -> Void
|_args| {
Ok(Val::Nil)
}
};
#[test]
fn argvec_optional_collect_u64() {
let args = vec![ArgSpec::from(1u64), ArgSpec::from(b"supplied")];
assert_eq!(
Err(Error::TypeError),
OPTIONAL_COLLECT_U64.argvec(None, args)
)
}