mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
This reduces std::mem::size_of::<Value>() to 16 bytes. String values are also efficiently copied like Objects, arrays, sets etc. When multiple function rules are evaluated, ensure that constant argument values match before running the rule. If actual parameter does not match the constant parameter, then the rule is skipped. Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
181 lines
5.1 KiB
Rust
181 lines
5.1 KiB
Rust
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
#![cfg(test)]
|
|
|
|
use anyhow::Result;
|
|
use regorus::*;
|
|
|
|
#[test]
|
|
fn non_string_key() -> Result<()> {
|
|
let mut obj = Value::new_object();
|
|
|
|
obj.as_object_mut()?.insert(Value::Null, Value::Null);
|
|
obj.as_object_mut()?.insert(Value::Bool(false), Value::Null);
|
|
obj.as_object_mut()?
|
|
.insert(Value::from_float(std::f64::consts::PI), Value::Null);
|
|
obj.as_object_mut()?.insert(
|
|
Value::from_array(vec![
|
|
Value::Bool(true),
|
|
Value::Null,
|
|
Value::from_float(std::f64::consts::PI),
|
|
]),
|
|
Value::Null,
|
|
);
|
|
|
|
let mut set = Value::new_set();
|
|
set.as_set_mut()?.insert(Value::Bool(true));
|
|
set.as_set_mut()?.insert(Value::Bool(false));
|
|
set.as_set_mut()?.insert(Value::Bool(true));
|
|
set.as_set_mut()?
|
|
.insert(Value::from_float(std::f64::consts::PI));
|
|
obj.as_object_mut()?.insert(set, Value::Null);
|
|
|
|
obj.as_object_mut()?.insert(Value::Undefined, Value::Null);
|
|
|
|
let key_obj = obj.clone();
|
|
obj.as_object_mut()?.insert(key_obj, Value::Null);
|
|
|
|
let json = serde_json::to_string_pretty(&obj)?;
|
|
println!("{json}");
|
|
|
|
let expected = r#"{
|
|
"null": null,
|
|
"false": null,
|
|
"3.141592653589793": null,
|
|
"[true,null,3.141592653589793]": null,
|
|
"{\"null\":null,\"false\":null,\"3.141592653589793\":null,\"[true,null,3.141592653589793]\":null,\"[false,true,3.141592653589793]\":null,\"\\\"<undefined>\\\"\":null}": null,
|
|
"[false,true,3.141592653589793]": null,
|
|
"\"<undefined>\"": null
|
|
}"#;
|
|
|
|
assert_eq!(json, expected);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn serialize_number() -> Result<()> {
|
|
// Check that integer values are serialized without fractional part
|
|
assert_eq!(serde_json::to_string_pretty(&Value::from_float(1.0))?, "1");
|
|
assert_eq!(
|
|
serde_json::to_string_pretty(&Value::from_float(-1.0))?,
|
|
"-1"
|
|
);
|
|
|
|
// Ensure that fractional parts are also serialized.
|
|
assert_eq!(
|
|
serde_json::to_string_pretty(&Value::from_float(1.1))?,
|
|
"1.1"
|
|
);
|
|
assert_eq!(
|
|
serde_json::to_string_pretty(&Value::from_float(-1.1))?,
|
|
"-1.1"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn display_number() {
|
|
use ordered_float::OrderedFloat;
|
|
let n = Number(OrderedFloat(123456f64));
|
|
assert_eq!(format!("{}", &n), "123456");
|
|
}
|
|
|
|
#[test]
|
|
fn serialize_string() -> Result<()> {
|
|
assert_eq!(
|
|
Value::String("Hello, World\n".into()).to_json_str()?,
|
|
"\"Hello, World\\n\""
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn constructors() -> Result<()> {
|
|
assert_eq!(Value::new_object(), Value::from_json_str("{}")?);
|
|
assert!(Value::new_set().as_set()?.is_empty());
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn value_as_index() -> Result<()> {
|
|
let idx = Value::from_float(2.0);
|
|
|
|
let mut item = Value::new_array();
|
|
item.as_array_mut()?.push(Value::from_float(3.0));
|
|
item.as_array_mut()?.push(Value::from_float(4.0));
|
|
item.as_array_mut()?.push(Value::from_float(5.0));
|
|
|
|
// Check case of item present.
|
|
assert_eq!(&Value::from_json_str("[1, 2, [3, 4, 5]]")?[&idx], &item);
|
|
|
|
// Check case of item not present.
|
|
let idx = Value::from_float(5.0);
|
|
assert_eq!(
|
|
&Value::from_json_str("[1, 2, [3, 4, 5]]")?[&idx],
|
|
&Value::Undefined
|
|
);
|
|
|
|
// Check case of non indexable item.
|
|
assert_eq!(&Value::Undefined[&idx], &Value::Undefined);
|
|
assert_eq!(&Value::Null[&idx], &Value::Undefined);
|
|
assert_eq!(&Value::Bool(true)[&idx], &Value::Undefined);
|
|
assert_eq!(&Value::String("Hello".into())[&idx], &Value::Undefined);
|
|
assert_eq!(&Value::new_set()[&idx], &Value::Undefined);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn string_as_index() -> Result<()> {
|
|
let obj = Value::from_json_str(r#"{ "a" : 5, "b" : 6 }"#)?;
|
|
assert_eq!(&obj["a"], &Value::from_float(5.0));
|
|
assert_eq!(&obj[&"b".to_owned()], &Value::from_float(6.0));
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn usize_as_index() -> Result<()> {
|
|
assert_eq!(
|
|
&Value::from_json_str("[1, 2, 3]")?[0],
|
|
&Value::from_float(1.0)
|
|
);
|
|
assert_eq!(&Value::from_json_str("[1, 2, 3]")?[5], &Value::Undefined);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn api() -> Result<()> {
|
|
assert!(&Value::from_json_str("{}")?.as_object()?.is_empty());
|
|
let mut v = Value::new_object();
|
|
v.as_object_mut()?
|
|
.insert(Value::String("a".into()), Value::from_float(3.145));
|
|
assert_eq!(v["a"], Value::from_float(3.145));
|
|
assert_eq!(v.as_object()?.len(), 1);
|
|
|
|
// Null
|
|
assert!(Value::Null.is_null());
|
|
|
|
let v = Value::new_set();
|
|
assert_eq!(v.as_set()?.len(), 0);
|
|
|
|
// Check invalid api calls.
|
|
assert!(Value::Undefined.as_object().is_err());
|
|
assert!(Value::Undefined.as_object_mut().is_err());
|
|
|
|
assert!(Value::Null.as_set().is_err());
|
|
assert!(Value::Null.as_set_mut().is_err());
|
|
|
|
assert!(Value::String("anc".into()).as_array().is_err());
|
|
assert!(Value::String("anc".into()).as_array_mut().is_err());
|
|
|
|
assert!(Value::new_object().as_number().is_err());
|
|
assert!(Value::new_object().as_number_mut().is_err());
|
|
|
|
assert!(Value::from_float(5.6).as_bool().is_err());
|
|
assert!(Value::from_float(5.6).as_bool_mut().is_err());
|
|
Ok(())
|
|
}
|