[oden-js] Fix bug with repeated arguments

This commit is contained in:
John Doty 2023-06-24 23:02:43 -07:00
parent b6f6d908d2
commit 82c386fd0f
3 changed files with 297 additions and 7 deletions

View file

@ -216,7 +216,7 @@ where
let vc = C::try_from_value(args[2], &context)?;
let vd = D::try_from_value(args[3], &context)?;
let ve = E::try_from_value(args[4], &context)?;
let vf = F::try_from_value(args[4], &context)?;
let vf = F::try_from_value(args[5], &context)?;
let res = self(context, va, vb, vc, vd, ve, vf);
res.into_res(context)
}
@ -252,8 +252,8 @@ where
let vc = C::try_from_value(args[2], &context)?;
let vd = D::try_from_value(args[3], &context)?;
let ve = E::try_from_value(args[4], &context)?;
let vf = F::try_from_value(args[4], &context)?;
let vg = G::try_from_value(args[4], &context)?;
let vf = F::try_from_value(args[5], &context)?;
let vg = G::try_from_value(args[6], &context)?;
let res = self(context, va, vb, vc, vd, ve, vf, vg);
res.into_res(context)
}
@ -290,10 +290,290 @@ where
let vc = C::try_from_value(args[2], &context)?;
let vd = D::try_from_value(args[3], &context)?;
let ve = E::try_from_value(args[4], &context)?;
let vf = F::try_from_value(args[4], &context)?;
let vg = G::try_from_value(args[4], &context)?;
let vh = H::try_from_value(args[4], &context)?;
let vf = F::try_from_value(args[5], &context)?;
let vg = G::try_from_value(args[6], &context)?;
let vh = H::try_from_value(args[7], &context)?;
let res = self(context, va, vb, vc, vd, ve, vf, vg, vh);
res.into_res(context)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Context, Error, EvalFlags, Result, Runtime};
use assert_matches::assert_matches;
#[test]
fn no_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(|_: &ContextRef| -> Result<f32> { Ok(0.0) })
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function()", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("0"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn one_argument() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(|_: &ContextRef, a: f32| -> Result<f32> { Ok(a) })
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("1"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function()", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn two_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(|_: &ContextRef, a: f32, b: f32| -> Result<f32> { Ok(a + b) })
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("3"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn three_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(|_: &ContextRef, a: f32, b: f32, c: f32| -> Result<f32> { Ok(a + b + c) })
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2,3)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("6"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1,2)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3,4)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn four_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(
|_: &ContextRef, a: f32, b: f32, c: f32, d: f32| -> Result<f32> {
Ok(a + b + c + d)
},
)
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2,3,4)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("10"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1,2,3)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3,4,5)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn five_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(
|_: &ContextRef, a: f32, b: f32, c: f32, d: f32, e: f32| -> Result<f32> {
Ok(a + b + c + d + e)
},
)
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2,3,4,5)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("15"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1,2,3,4)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3,4,5,6)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn six_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(
|_: &ContextRef, a: f32, b: f32, c: f32, d: f32, e: f32, f: f32| -> Result<f32> {
Ok(a + b + c + d + e + f)
},
)
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2,3,4,5,6)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("21"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1,2,3,4,5)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3,4,5,6,7)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn seven_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(
|_: &ContextRef,
a: f32,
b: f32,
c: f32,
d: f32,
e: f32,
f: f32,
g: f32|
-> Result<f32> { Ok(a + b + c + d + e + f + g) },
)
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2,3,4,5,6,7)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("28"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1,2,3,4,5,6)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3,4,5,6,7,8)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
#[test]
fn eight_arguments() {
let rt = Runtime::new();
let ctx = Context::new(rt);
let the_function = ctx
.new_fn(
|_: &ContextRef,
a: f32,
b: f32,
c: f32,
d: f32,
e: f32,
f: f32,
g: f32,
h: f32|
-> Result<f32> { Ok(a + b + c + d + e + f + g + h) },
)
.unwrap();
ctx.global_object()
.unwrap()
.set_property(&ctx, "the_function", &the_function)
.expect("Should be able to set the function");
let val = ctx
.eval("the_function(1,2,3,4,5,6,7,8)", "script", EvalFlags::NONE)
.unwrap();
assert_eq!(String::from("36"), val.to_string(&ctx).unwrap());
let val = ctx.eval("the_function(1,2,3,4,5,6,7)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
let val = ctx.eval("the_function(1,2,3,4,5,6,7,8,9)", "script", EvalFlags::NONE);
assert_matches!(val, Err(Error::Exception(..)));
}
}