#![allow(clippy::result_large_err)]
use std::collections::HashMap;
use std::rc::Rc;
use qlexpress::aparser::import_manager::QLImport;
use qlexpress::default_class_supplier::DefaultClassSupplier;
use qlexpress::init_options::InitOptions;
use qlexpress::ql_options::QLOptions;
use qlexpress::security::ql_security_strategy::QLSecurityStrategy;
use qlexpress::Express4Runner;
fn runner_with_default_import(imports: Vec<QLImport>) -> Express4Runner {
let mut supplier = DefaultClassSupplier::instance();
supplier.register("com.example.Calc");
Express4Runner::with_init_options(
InitOptions::builder()
.class_supplier(Rc::new(supplier))
.add_default_import(imports)
.security_strategy(QLSecurityStrategy::open())
.build(),
)
}
fn opts() -> QLOptions {
QLOptions::builder().build()
}
#[test]
fn default_import_unqualified_class() {
let mut runner = runner_with_default_import(vec![QLImport::import_cls("com.example.Calc")]);
use qlexpress::runtime::native_type::NativeType;
let mut calc = NativeType::named("com.example.Calc");
calc.static_methods.insert(
"answer".to_string(),
std::rc::Rc::new(|_bean, _args| Ok(qlexpress::runtime::value::DataValue::Long(42))),
);
runner.register_native_type(calc);
let r = runner
.execute("Calc.answer()", HashMap::new(), &opts())
.expect("ok")
.into_result();
assert_eq!(r, qlexpress::runtime::value::DataValue::Long(42));
}
#[test]
fn without_default_import_unqualified_fails() {
let mut supplier = DefaultClassSupplier::instance();
supplier.register("com.example.Calc");
let runner = Express4Runner::with_init_options(
InitOptions::builder()
.class_supplier(Rc::new(supplier))
.security_strategy(QLSecurityStrategy::open())
.build(),
);
let r = runner.execute("Calc.answer()", HashMap::new(), &opts());
assert!(r.is_err());
}
#[test]
fn existing_runner_observes_later_default_import_mutation() {
use qlexpress::runtime::native_type::NativeType;
use qlexpress::runtime::value::DataValue;
let mut supplier = DefaultClassSupplier::instance();
supplier.register("com.example.Calc");
let options = InitOptions::builder()
.class_supplier(Rc::new(supplier))
.security_strategy(QLSecurityStrategy::open())
.build();
let retained_options = options.clone();
let mut runner = Express4Runner::with_init_options(options);
let mut calc = NativeType::named("com.example.Calc");
calc.static_methods.insert(
"answer".to_string(),
Rc::new(|_bean, _args| Ok(DataValue::Long(42))),
);
runner.register_native_type(calc);
assert!(
runner
.execute("Calc.answer()", HashMap::new(), &opts())
.is_err(),
"unqualified type must not resolve before the late import"
);
retained_options
.default_import_mut()
.push(QLImport::import_cls("com.example.Calc"));
assert_eq!(
runner
.execute("Calc.answer()", HashMap::new(), &opts())
.expect("existing runner must observe the late import")
.into_result(),
DataValue::Long(42)
);
}