diff --git a/lib/rhai/engine.ex b/lib/rhai/engine.ex index f67095e..cd6dc8f 100644 --- a/lib/rhai/engine.ex +++ b/lib/rhai/engine.ex @@ -60,6 +60,28 @@ defmodule Rhai.Engine do Rhai.Native.engine_eval_with_scope(engine_resource, scope_resource, script) end + @doc """ + Set the maximum length of arrays (0 for unlimited). + + Not available under `unchecked` or `no_index`. + """ + @spec set_max_array_size(t(), integer()) :: t() + def set_max_array_size(%__MODULE__{resource: resource} = engine, max_size) do + Rhai.Native.engine_set_max_array_size(resource, max_size) + + engine + end + + @doc """ + The maximum length of arrays (0 for unlimited). + + Zero under `no_index`. + """ + @spec max_array_size(t()) :: integer() + def max_array_size(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_array_size(resource) + end + @doc """ Set whether to raise error if an object map property does not exist. """ @@ -78,6 +100,312 @@ defmodule Rhai.Engine do Rhai.Native.engine_fail_on_invalid_map_property(resource) end + @doc """ + Set whether anonymous function is allowed. + + Not available under `no_function`. + """ + @spec set_allow_anonymous_fn(t(), boolean) :: t() + def set_allow_anonymous_fn(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_anonymous_fn(resource, enable) + + engine + end + + @doc """ + Is anonymous function allowed? Default is true. + + Not available under `no_function`. + """ + @spec allow_anonymous_fn?(t()) :: boolean + def allow_anonymous_fn?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_anonymous_fn(resource) + end + + @doc """ + Set whether `if`-expression is allowed. + """ + @spec set_allow_if_expression(t(), boolean) :: t() + def set_allow_if_expression(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_if_expression(resource, enable) + + engine + end + + @doc """ + Is if-expression allowed? Default is `true`. + """ + @spec allow_if_expression?(t()) :: boolean + def allow_if_expression?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_if_expression(resource) + end + + @doc """ + Set whether loop expressions are allowed. + """ + @spec set_allow_loop_expressions(t(), boolean) :: t() + def set_allow_loop_expressions(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_loop_expressions(resource, enable) + + engine + end + + @doc """ + Are loop-expression allowed? Default is `true`. + """ + @spec allow_loop_expressions?(t()) :: boolean + def allow_loop_expressions?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_loop_expressions(resource) + end + + @doc """ + Set whether looping is allowed. + """ + @spec set_allow_looping(t(), boolean) :: t() + def set_allow_looping(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_looping(resource, enable) + + engine + end + + @doc """ + Is looping allowed? Default is `true`. + """ + @spec allow_looping?(t()) :: boolean + def allow_looping?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_looping(resource) + end + + @doc """ + Set whether shadowing is allowed. + """ + @spec set_allow_shadowing(t(), boolean) :: t() + def set_allow_shadowing(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_shadowing(resource, enable) + + engine + end + + @doc """ + Is shadowing allowed? Default is `true`. + """ + @spec allow_shadowing?(t()) :: boolean + def allow_shadowing?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_shadowing(resource) + end + + @doc """ + Set whether statement_expression is allowed. + """ + @spec set_allow_statement_expression(t(), boolean) :: t() + def set_allow_statement_expression(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_statement_expression(resource, enable) + + engine + end + + @doc """ + Is statement_expression allowed? Default is `true`. + """ + @spec allow_statement_expression?(t()) :: boolean + def allow_statement_expression?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_statement_expression(resource) + end + + @doc """ + Set whether `switch` expression is allowed. + """ + @spec set_allow_switch_expression(t(), boolean) :: t() + def set_allow_switch_expression(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_allow_switch_expression(resource, enable) + + engine + end + + @doc """ + Is `switch` expression allowed? Default is `true`. + """ + @spec allow_switch_expression?(t()) :: boolean + def allow_switch_expression?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_allow_switch_expression(resource) + end + + @doc """ + Set whether fast operators mode is enabled. + """ + @spec set_fast_operators(t(), boolean) :: t() + def set_fast_operators(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_fast_operators(resource, enable) + + engine + end + + @doc """ + Is fast operators mode enabled? Default is `false`. + """ + @spec fast_operators?(t()) :: boolean + def fast_operators?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_fast_operators(resource) + end + + @doc """ + Set the maximum levels of function calls allowed for a script in order to avoid infinite recursion and stack overflows. + + Not available under `unchecked` or `no_function`. + """ + @spec set_max_call_levels(t(), non_neg_integer()) :: t() + def set_max_call_levels(%__MODULE__{resource: resource} = engine, levels) do + Rhai.Native.engine_set_max_call_levels(resource, levels) + + engine + end + + @doc """ + Is fast operators mode enabled? Default is `false`. + """ + @spec max_call_levels(t()) :: non_neg_integer() + def max_call_levels(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_call_levels(resource) + end + + @doc """ + Set the depth limits for expressions (0 for unlimited). + + Not available under `unchecked`. + """ + @spec set_max_expr_depths(t(), non_neg_integer(), non_neg_integer()) :: t() + def set_max_expr_depths( + %__MODULE__{resource: resource} = engine, + max_expr_depth, + max_function_expr_depth + ) do + Rhai.Native.engine_set_max_expr_depths(resource, max_expr_depth, max_function_expr_depth) + + engine + end + + @doc """ + The depth limit for expressions (0 for unlimited). + """ + @spec max_expr_depth(t()) :: non_neg_integer() + def max_expr_depth(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_expr_depth(resource) + end + + @doc """ + The depth limit for expressions in functions (0 for unlimited). + + Zero under `no_function`. + """ + @spec max_expr_depth(t()) :: non_neg_integer() + def max_function_expr_depth(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_function_expr_depth(resource) + end + + @doc """ + Set the maximum size of object maps (0 for unlimited). + + Not available under `unchecked` or `no_object`. + """ + @spec set_max_map_size(t(), non_neg_integer()) :: t() + def set_max_map_size(%__MODULE__{resource: resource} = engine, size) do + Rhai.Native.engine_set_max_map_size(resource, size) + + engine + end + + @doc """ + The maximum size of object maps (0 for unlimited). + + Zero under `no_object`. + """ + @spec max_map_size(t()) :: non_neg_integer() + def max_map_size(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_map_size(resource) + end + + @doc """ + Set the maximum number of imported modules allowed for a script. + + Not available under `unchecked` or `no_module`. + """ + @spec set_max_modules(t(), non_neg_integer()) :: t() + def set_max_modules(%__MODULE__{resource: resource} = engine, modules) do + Rhai.Native.engine_set_max_modules(resource, modules) + + engine + end + + @doc """ + The maximum number of imported modules allowed for a script. + + Zero under `no_module`. + """ + @spec max_modules(t()) :: non_neg_integer() + def max_modules(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_modules(resource) + end + + @doc """ + Set the maximum number of operations allowed for a script to run to avoid consuming too much resources (0 for unlimited). + + Not available under `unchecked`. + """ + @spec set_max_operations(t(), non_neg_integer()) :: t() + def set_max_operations(%__MODULE__{resource: resource} = engine, operations) do + Rhai.Native.engine_set_max_operations(resource, operations) + + engine + end + + @doc """ + The maximum number of operations allowed for a script to run (0 for unlimited). + + Not available under `unchecked`. + """ + @spec max_operations(t()) :: non_neg_integer() + def max_operations(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_operations(resource) + end + + @doc """ + Set the maximum length, in bytes, of strings (0 for unlimited). + + Not available under `unchecked`. + """ + @spec set_max_string_size(t(), non_neg_integer()) :: t() + def set_max_string_size(%__MODULE__{resource: resource} = engine, string_size) do + Rhai.Native.engine_set_max_string_size(resource, string_size) + + engine + end + + @doc """ + The maximum length, in bytes, of strings (0 for unlimited). + """ + @spec max_string_size(t()) :: non_neg_integer() + def max_string_size(%__MODULE__{resource: resource}) do + Rhai.Native.engine_max_string_size(resource) + end + + @doc """ + Set whether strict variables mode is enabled. + """ + @spec set_strict_variables(t(), boolean) :: t() + def set_strict_variables(%__MODULE__{resource: resource} = engine, enable) do + Rhai.Native.engine_set_strict_variables(resource, enable) + + engine + end + + @doc """ + Is strict variables mode enabled? Default is `false`. + """ + @spec strict_variables?(t()) :: boolean + def strict_variables?(%__MODULE__{resource: resource}) do + Rhai.Native.engine_strict_variables(resource) + end + def wrap_resource(resource) do %__MODULE__{ resource: resource, diff --git a/lib/rhai/native.ex b/lib/rhai/native.ex index a6bbb5c..1748a5e 100644 --- a/lib/rhai/native.ex +++ b/lib/rhai/native.ex @@ -34,6 +34,40 @@ defmodule Rhai.Native do def engine_eval_with_scope(_engine, _scope, _script), do: err() def engine_set_fail_on_invalid_map_property(_engine, _flag), do: err() def engine_fail_on_invalid_map_property(_engine), do: err() + def engine_set_max_array_size(_engine, _flag), do: err() + def engine_max_array_size(_engine), do: err() + def engine_set_allow_anonymous_fn(_engine, _flag), do: err() + def engine_allow_anonymous_fn(_engine), do: err() + def engine_set_allow_if_expression(_engine, _flag), do: err() + def engine_allow_if_expression(_engine), do: err() + def engine_set_allow_loop_expressions(_engine, _flag), do: err() + def engine_allow_loop_expressions(_engine), do: err() + def engine_set_allow_looping(_engine, _flag), do: err() + def engine_allow_looping(_engine), do: err() + def engine_set_allow_shadowing(_engine, _flag), do: err() + def engine_allow_shadowing(_engine), do: err() + def engine_set_allow_statement_expression(_engine, _flag), do: err() + def engine_allow_statement_expression(_engine), do: err() + def engine_set_allow_switch_expression(_engine, _flag), do: err() + def engine_allow_switch_expression(_engine), do: err() + def engine_set_fast_operators(_engine, _flag), do: err() + def engine_fast_operators(_engine), do: err() + def engine_set_max_call_levels(_engine, _levels), do: err() + def engine_max_call_levels(_engine), do: err() + def engine_set_max_expr_depths(_engine, _max_expr_depth, _max_function_expr_depth), do: err() + def engine_max_expr_depth(_engine), do: err() + def engine_max_function_expr_depth(_engine), do: err() + def engine_set_max_map_size(_engine, _max_size), do: err() + def engine_max_map_size(_engine), do: err() + def engine_set_max_modules(_engine, _modules), do: err() + def engine_max_modules(_engine), do: err() + def engine_set_max_operations(_engine, _operations), do: err() + def engine_max_operations(_engine), do: err() + def engine_set_max_string_size(_engine, _max_len), do: err() + def engine_max_string_size(_engine), do: err() + def engine_set_strict_variables(_engine, _flag), do: err() + def engine_strict_variables(_engine), do: err() + # scope def scope_new, do: err() def scope_push_dynamic(_scope, _name, _value), do: err() diff --git a/native/rhai_rustler/src/engine.rs b/native/rhai_rustler/src/engine.rs index d013285..4554326 100644 --- a/native/rhai_rustler/src/engine.rs +++ b/native/rhai_rustler/src/engine.rs @@ -57,6 +57,104 @@ fn engine_compile( Ok(ast_resource) } +#[rustler::nif] +fn engine_set_allow_anonymous_fn(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_anonymous_fn(enable); +} + +#[rustler::nif] +fn engine_allow_anonymous_fn(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_anonymous_fn() +} + +#[rustler::nif] +fn engine_set_allow_if_expression(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_if_expression(enable); +} + +#[rustler::nif] +fn engine_allow_if_expression(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_if_expression() +} + +#[rustler::nif] +fn engine_set_allow_loop_expressions(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_loop_expressions(enable); +} + +#[rustler::nif] +fn engine_allow_loop_expressions(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_loop_expressions() +} + +#[rustler::nif] +fn engine_set_allow_looping(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_looping(enable); +} + +#[rustler::nif] +fn engine_allow_looping(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_looping() +} + +#[rustler::nif] +fn engine_set_allow_shadowing(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_shadowing(enable); +} + +#[rustler::nif] +fn engine_allow_shadowing(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_shadowing() +} + +#[rustler::nif] +fn engine_set_allow_statement_expression(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_statement_expression(enable); +} + +#[rustler::nif] +fn engine_allow_statement_expression(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_statement_expression() +} + +#[rustler::nif] +fn engine_set_allow_switch_expression(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_allow_switch_expression(enable); +} + +#[rustler::nif] +fn engine_allow_switch_expression(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.allow_switch_expression() +} + #[rustler::nif] fn engine_set_fail_on_invalid_map_property(resource: ResourceArc, enable: bool) { let mut engine = resource.engine.try_lock().unwrap(); @@ -70,3 +168,140 @@ fn engine_fail_on_invalid_map_property(resource: ResourceArc) -> engine.fail_on_invalid_map_property() } + +#[rustler::nif] +fn engine_set_fast_operators(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_fast_operators(enable); +} + +#[rustler::nif] +fn engine_fast_operators(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.fast_operators() +} + +#[rustler::nif] +fn engine_set_max_array_size(resource: ResourceArc, max_size: usize) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_array_size(max_size); +} + +#[rustler::nif] +fn engine_max_array_size(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_array_size() +} + +#[rustler::nif] +fn engine_set_max_call_levels(resource: ResourceArc, levels: usize) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_call_levels(levels); +} + +#[rustler::nif] +fn engine_max_call_levels(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_call_levels() +} + +#[rustler::nif] +fn engine_set_max_expr_depths( + resource: ResourceArc, + max_expr_depth: usize, + max_function_expr_depth: usize, +) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_expr_depths(max_expr_depth, max_function_expr_depth); +} + +#[rustler::nif] +fn engine_max_expr_depth(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_expr_depth() +} + +#[rustler::nif] +fn engine_max_function_expr_depth(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_function_expr_depth() +} + +#[rustler::nif] +fn engine_set_max_map_size(resource: ResourceArc, max_size: usize) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_map_size(max_size); +} + +#[rustler::nif] +fn engine_max_map_size(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_map_size() +} + +#[rustler::nif] +fn engine_set_max_modules(resource: ResourceArc, modules: usize) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_modules(modules); +} + +#[rustler::nif] +fn engine_max_modules(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_modules() +} + +#[rustler::nif] +fn engine_set_max_operations(resource: ResourceArc, operations: u64) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_operations(operations); +} + +#[rustler::nif] +fn engine_max_operations(resource: ResourceArc) -> u64 { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_operations() +} + +#[rustler::nif] +fn engine_set_max_string_size(resource: ResourceArc, max_len: usize) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_max_string_size(max_len); +} + +#[rustler::nif] +fn engine_max_string_size(resource: ResourceArc) -> usize { + let engine = resource.engine.try_lock().unwrap(); + + engine.max_string_size() +} + +#[rustler::nif] +fn engine_set_strict_variables(resource: ResourceArc, enable: bool) { + let mut engine = resource.engine.try_lock().unwrap(); + + engine.set_strict_variables(enable); +} + +#[rustler::nif] +fn engine_strict_variables(resource: ResourceArc) -> bool { + let engine = resource.engine.try_lock().unwrap(); + + engine.strict_variables() +} diff --git a/native/rhai_rustler/src/lib.rs b/native/rhai_rustler/src/lib.rs index 9611a40..3f19175 100644 --- a/native/rhai_rustler/src/lib.rs +++ b/native/rhai_rustler/src/lib.rs @@ -56,6 +56,39 @@ rustler::init!( engine_eval_with_scope, engine_set_fail_on_invalid_map_property, engine_fail_on_invalid_map_property, + engine_set_max_array_size, + engine_max_array_size, + engine_set_allow_anonymous_fn, + engine_allow_anonymous_fn, + engine_set_allow_if_expression, + engine_allow_if_expression, + engine_set_allow_loop_expressions, + engine_allow_loop_expressions, + engine_set_allow_looping, + engine_allow_looping, + engine_set_allow_shadowing, + engine_allow_shadowing, + engine_set_allow_statement_expression, + engine_allow_statement_expression, + engine_set_allow_switch_expression, + engine_allow_switch_expression, + engine_set_fast_operators, + engine_fast_operators, + engine_set_max_call_levels, + engine_max_call_levels, + engine_set_max_expr_depths, + engine_max_expr_depth, + engine_max_function_expr_depth, + engine_set_max_map_size, + engine_max_map_size, + engine_set_max_modules, + engine_max_modules, + engine_set_max_operations, + engine_max_operations, + engine_set_max_string_size, + engine_max_string_size, + engine_set_strict_variables, + engine_strict_variables, // scope scope_new, scope_push_dynamic, diff --git a/test/rhai/engine_test.exs b/test/rhai/engine_test.exs index 95e07ee..9b54dd6 100644 --- a/test/rhai/engine_test.exs +++ b/test/rhai/engine_test.exs @@ -26,7 +26,7 @@ defmodule Rhai.EngineTest do end end - describe "set_fail_on_invalid_map_property/2, fail_on_invalid_map_property?/0" do + describe "set_fail_on_invalid_map_property/2, fail_on_invalid_map_property?/1" do test "should return false by default" do engine = Engine.new() @@ -53,4 +53,251 @@ defmodule Rhai.EngineTest do assert {:error, {:parsing, _}} = Engine.compile(engine, "???") end end + + describe "set_max_array_size/2, max_array_size/1" do + test "should return an unlimited size by default" do + engine = Engine.new() + + assert 0 == Engine.max_array_size(engine) + end + + test "should set a max array size" do + assert 256 = Engine.new() |> Engine.set_max_array_size(256) |> Engine.max_array_size() + end + end + + describe "set_allow_anonymous_fn/2, allow_anonymous_fn?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.allow_anonymous_fn?(engine) + end + + test "should set the flag to false" do + refute Engine.new() |> Engine.set_allow_anonymous_fn(false) |> Engine.allow_anonymous_fn?() + end + end + + describe "set_allow_if_expression/2, allow_if_expression?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.allow_if_expression?(engine) + end + + test "should set the flag to false" do + refute Engine.new() + |> Engine.set_allow_if_expression(false) + |> Engine.allow_if_expression?() + end + end + + # FIXME: At the moment Rhai has a wrong default for this one, disabling the test until it gets fixed upstream + # describe "set_allow_loop_expressions/2, allow_loop_expressions/1" do + # test "should return true by default" do + # engine = Engine.new() + # + # assert Engine.allow_loop_expressions?(engine) + # end + # + # test "should set the flag to false" do + # engine = Engine.new() + # + # refute Engine.new() + # |> Engine.set_allow_loop_expressions(false) + # |> Engine.allow_loop_expressions?() + # end + # end + + describe "set_allow_looping/2, allow_looping?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.allow_looping?(engine) + end + + test "should set the flag to false" do + refute Engine.new() |> Engine.set_allow_looping(false) |> Engine.allow_looping?() + end + end + + describe "set_allow_shadowing/2, allow_shadowing?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.allow_shadowing?(engine) + end + + test "should set the flag to false" do + refute Engine.new() |> Engine.set_allow_shadowing(false) |> Engine.allow_shadowing?() + end + end + + describe "set_allow_statement_expression/2, allow_statement_expression?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.allow_statement_expression?(engine) + end + + test "should set the flag to false" do + refute Engine.new() + |> Engine.set_allow_statement_expression(false) + |> Engine.allow_statement_expression?() + end + end + + describe "set_allow_switch_expression/2, allow_switch_expression?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.allow_switch_expression?(engine) + end + + test "should set the flag to false" do + refute Engine.new() + |> Engine.set_allow_switch_expression(false) + |> Engine.allow_switch_expression?() + end + end + + describe "set_fast_operators/2, fast_operators?/1" do + test "should return true by default" do + engine = Engine.new() + + assert Engine.fast_operators?(engine) + end + + test "should set the flag to false" do + refute Engine.new() + |> Engine.set_fast_operators(false) + |> Engine.fast_operators?() + end + end + + describe "set_allow_max_call_levels/2, allow_max_call_levels/1" do + test "should return true by default" do + engine = Engine.new() + + assert 64 == Engine.max_call_levels(engine) + end + + test "should set the flag to false" do + assert 256 == + Engine.new() + |> Engine.set_max_call_levels(256) + |> Engine.max_call_levels() + end + end + + describe "set_max_call_levels/2, max_call_levels/1" do + test "should return 64 by default" do + engine = Engine.new() + + assert 64 == Engine.max_call_levels(engine) + end + + test "should set the size to 256" do + assert 256 == + Engine.new() + |> Engine.set_max_call_levels(256) + |> Engine.max_call_levels() + end + end + + describe "set_max_expr_depths/3, max_expr_depth/1, max_function_expr_depth/1" do + test "should return 64 by default" do + engine = Engine.new() + + assert 64 == Engine.max_expr_depth(engine) + end + + test "should set expr depth" do + assert 256 == + Engine.new() + |> Engine.set_max_expr_depths(256, 512) + |> Engine.max_expr_depth() + end + + test "should set max function expr depth" do + assert 512 == + Engine.new() + |> Engine.set_max_expr_depths(256, 512) + |> Engine.max_function_expr_depth() + end + end + + describe "set_max_map_size/2, max_map_size/1" do + test "should return 0 by default" do + engine = Engine.new() + + assert 0 == Engine.max_map_size(engine) + end + + test "should set the size to 256" do + assert 256 == + Engine.new() + |> Engine.set_max_map_size(256) + |> Engine.max_map_size() + end + end + + describe "set_max_modules/2, max_modules/1" do + test "should return the default" do + engine = Engine.new() + + assert 18_446_744_073_709_551_615 == Engine.max_modules(engine) + end + + test "should set modules number to 256" do + assert 256 == + Engine.new() + |> Engine.set_max_modules(256) + |> Engine.max_modules() + end + end + + describe "set_max_operations/2, max_operations/1" do + test "should return 0 by default" do + engine = Engine.new() + + assert 0 == Engine.max_operations(engine) + end + + test "should set ops limit to 256" do + assert 256 == + Engine.new() + |> Engine.set_max_operations(256) + |> Engine.max_operations() + end + end + + describe "set_max_string_size/2, max_string_size/1" do + test "should return 0 by default" do + engine = Engine.new() + + assert 0 == Engine.max_string_size(engine) + end + + test "should set string size limit to 256" do + assert 256 == + Engine.new() + |> Engine.set_max_string_size(256) + |> Engine.max_string_size() + end + end + + describe "set_strict_variables/2, strict_variables/1" do + test "should return false by default" do + engine = Engine.new() + + refute Engine.strict_variables?(engine) + end + + test "should set strict variables mode to true" do + assert Engine.new() + |> Engine.set_strict_variables(true) + |> Engine.strict_variables?() + end + end end