diff --git a/lumen_runtime/src/otp/erlang.rs b/lumen_runtime/src/otp/erlang.rs index bb0b62346..48a405cbe 100644 --- a/lumen_runtime/src/otp/erlang.rs +++ b/lumen_runtime/src/otp/erlang.rs @@ -700,6 +700,11 @@ pub fn is_greater_than_2(left: Term, right: Term) -> Term { left.gt(&right).into() } +/// `>=/2` infix operator. Floats and integers are converted. +pub fn is_greater_than_or_equal_2(left: Term, right: Term) -> Term { + left.ge(&right).into() +} + pub fn is_integer_1(term: Term) -> Term { match term.tag() { SmallInteger => true, diff --git a/lumen_runtime/src/otp/erlang/tests.rs b/lumen_runtime/src/otp/erlang/tests.rs index 742952ea2..56c9b6723 100644 --- a/lumen_runtime/src/otp/erlang/tests.rs +++ b/lumen_runtime/src/otp/erlang/tests.rs @@ -56,6 +56,7 @@ mod is_bitstring_1; mod is_boolean_1; mod is_float_1; mod is_greater_than_2; +mod is_greater_than_or_equal_2; mod is_integer_1; mod is_less_than_2; mod is_list_1; diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2.rs new file mode 100644 index 000000000..fff355bc3 --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2.rs @@ -0,0 +1,31 @@ +use super::*; + +mod with_atom_left; +mod with_big_integer_left; +mod with_empty_list_left; +mod with_external_pid_left; +mod with_float_left; +mod with_heap_binary_left; +mod with_list_left; +mod with_local_pid_left; +mod with_local_reference_left; +mod with_map_left; +mod with_small_integer_left; +mod with_subbinary_left; +mod with_tuple_left; + +fn is_greater_than_or_equal(left: L, right: R, expected: bool) +where + L: FnOnce(&mut Process) -> Term, + R: FnOnce(Term, &mut Process) -> Term, +{ + with_process(|mut process| { + let left = left(&mut process); + let right = right(left, &mut process); + + assert_eq!( + erlang::is_greater_than_or_equal_2(left, right), + expected.into() + ); + }); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_atom_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_atom_left.rs new file mode 100644 index 000000000..75ff96db3 --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_atom_left.rs @@ -0,0 +1,116 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_greater_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("keft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_same_atom_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_atom_value_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("left", DoNotCare).unwrap(), true); +} + +#[test] +fn with_greater_atom_returns_false() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), false); +} + +#[test] +fn with_local_reference_right_returns_false() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), false); +} + +#[test] +fn with_local_pid_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), false); +} + +#[test] +fn with_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |_| Term::str_to_atom("left", DoNotCare).unwrap(), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_big_integer_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_big_integer_left.rs new file mode 100644 index 000000000..1fc683f49 --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_big_integer_left.rs @@ -0,0 +1,140 @@ +use super::*; + +#[test] +fn with_greater_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_greater_small_integer_right_returns_false() { + super::is_greater_than_or_equal( + |mut process| (crate::integer::small::MIN - 1).into_process(&mut process), + |_, mut process| crate::integer::small::MIN.into_process(&mut process), + false, + ); +} + +#[test] +fn with_greater_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MIN - 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_same_big_integer_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true) +} + +#[test] +fn with_same_value_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_greater_big_integer_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 2).into_process(&mut process), + false, + ) +} + +#[test] +fn with_greater_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_greater_float_right_returns_false() { + super::is_greater_than_or_equal( + |mut process| (crate::integer::small::MIN - 1).into_process(&mut process), + |_, mut process| 0.0.into_process(&mut process), + false, + ); +} + +#[test] +fn with_atom_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), false); +} + +#[test] +fn with_local_reference_right_returns_false() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), false); +} + +#[test] +fn with_local_pid_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), false); +} + +#[test] +fn with_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_empty_list_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_empty_list_left.rs new file mode 100644 index 000000000..5d474521b --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_empty_list_left.rs @@ -0,0 +1,94 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_tuple_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + true, + ); +} + +#[test] +fn with_map_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::slice_to_map(&[], &mut process), true); +} + +#[test] +fn with_empty_list_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, true); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal(|_| Term::EMPTY_LIST, right, expected); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_external_pid_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_external_pid_left.rs new file mode 100644 index 000000000..1e1a8095f --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_external_pid_left.rs @@ -0,0 +1,122 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_greater_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 1, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_same_external_pid_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_greater_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 3, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_float_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_float_left.rs new file mode 100644 index 000000000..c9fd9b1ce --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_float_left.rs @@ -0,0 +1,119 @@ +use super::*; + +#[test] +fn with_greater_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| (-1).into_process(&mut process), true) +} + +#[test] +fn with_greater_small_integer_right_returns_false() { + is_greater_than_or_equal(|_, mut process| 1.into_process(&mut process), false) +} + +#[test] +fn with_greater_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MIN - 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_greater_big_integer_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + false, + ) +} + +#[test] +fn with_greater_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| (-1.0).into_process(&mut process), true) +} + +#[test] +fn with_greater_float_right_returns_false() { + is_greater_than_or_equal(|_, mut process| 1.0.into_process(&mut process), false) +} + +#[test] +fn with_atom_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), false); +} + +#[test] +fn with_local_reference_right_returns_false() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), false); +} + +#[test] +fn with_local_pid_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), false); +} + +#[test] +fn with_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| 0.0.into_process(&mut process), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_heap_binary_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_heap_binary_left.rs new file mode 100644 index 000000000..1115c49bc --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_heap_binary_left.rs @@ -0,0 +1,230 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_tuple_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + true, + ); +} + +#[test] +fn with_map_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::slice_to_map(&[], &mut process), true); +} + +#[test] +fn with_empty_list_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, true); +} + +#[test] +fn with_list_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_prefix_heap_binary_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[1], &mut process), + true, + ); +} + +#[test] +fn with_same_length_heap_binary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[0], &mut process), + true, + ); +} + +#[test] +fn with_longer_heap_binary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[0, 1, 2], &mut process), + true, + ); +} + +#[test] +fn with_same_heap_binary_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_heap_binary_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[1, 1], &mut process), + true, + ) +} + +#[test] +fn with_shorter_heap_binary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[2], &mut process), + false, + ); +} + +#[test] +fn with_heap_binary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[2, 1], &mut process), + false, + ); +} + +#[test] +fn with_heap_binary_with_different_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[1, 2], &mut process), + false, + ); +} + +#[test] +fn with_prefix_subbinary_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[1], &mut process); + Term::subbinary(original, 0, 0, 1, 0, &mut process) + }, + true, + ); +} + +#[test] +fn with_same_length_subbinary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[0, 1], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + true, + ); +} + +#[test] +fn with_longer_subbinary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| bitstring!(0, 1, 0b10 :: 2, &mut process), + true, + ); +} + +#[test] +fn with_same_subbinary_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_subbinary_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[1, 1], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + true, + ) +} + +#[test] +fn with_shorter_subbinary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[2], &mut process); + Term::subbinary(original, 0, 0, 1, 0, &mut process) + }, + false, + ); +} + +#[test] +fn with_subbinary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[2, 1], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + false, + ); +} + +#[test] +fn with_subbinary_with_different_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[1, 2], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + false, + ); +} + +#[test] +fn with_subbinary_with_value_with_shorter_length_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1, 1 :: 1, &mut process), false) +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| Term::slice_to_binary(&[1, 1], &mut process), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_list_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_list_left.rs new file mode 100644 index 000000000..ecde5f53a --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_list_left.rs @@ -0,0 +1,137 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_tuple_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + true, + ); +} + +#[test] +fn with_map_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::slice_to_map(&[], &mut process), true); +} + +#[test] +fn with_empty_list_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, true); +} + +#[test] +fn with_greater_list_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 0.into_process(&mut process), + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_list_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_list_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_greater_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 2.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_local_pid_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_local_pid_left.rs new file mode 100644 index 000000000..c6c30e720 --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_local_pid_left.rs @@ -0,0 +1,112 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_greater_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 0).unwrap(), true); +} + +#[test] +fn with_same_local_pid_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_greater_local_pid_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::local_pid(1, 1).unwrap(), false); +} + +#[test] +fn with_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal(|_| Term::local_pid(0, 1).unwrap(), right, expected); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_local_reference_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_local_reference_left.rs new file mode 100644 index 000000000..224c7c63f --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_local_reference_left.rs @@ -0,0 +1,125 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_greater_local_reference_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::number_to_local_reference(0, &mut process), + true, + ); +} + +#[test] +fn with_same_local_reference_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_local_reference_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::number_to_local_reference(1, &mut process), + true, + ); +} + +#[test] +fn with_greater_local_reference_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::number_to_local_reference(2, &mut process), + false, + ); +} + +#[test] +fn with_local_pid_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), false); +} + +#[test] +fn with_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| Term::number_to_local_reference(1, &mut process), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_map_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_map_left.rs new file mode 100644 index 000000000..e5f32f75d --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_map_left.rs @@ -0,0 +1,269 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_tuple_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + true, + ); +} + +#[test] +fn with_smaller_map_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[( + Term::str_to_atom("a", DoNotCare).unwrap(), + 1.into_process(&mut process), + )], + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_size_map_with_greater_keys_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("a", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ( + Term::str_to_atom("b", DoNotCare).unwrap(), + 3.into_process(&mut process), + ), + ], + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_size_map_with_same_keys_with_greater_values_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("b", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ( + Term::str_to_atom("c", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ], + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_map_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_map_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("b", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ( + Term::str_to_atom("c", DoNotCare).unwrap(), + 3.into_process(&mut process), + ), + ], + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_size_map_with_same_keys_with_greater_values_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("b", DoNotCare).unwrap(), + 3.into_process(&mut process), + ), + ( + Term::str_to_atom("c", DoNotCare).unwrap(), + 4.into_process(&mut process), + ), + ], + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_same_size_map_with_greater_keys_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("c", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ( + Term::str_to_atom("d", DoNotCare).unwrap(), + 3.into_process(&mut process), + ), + ], + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_greater_size_map_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("a", DoNotCare).unwrap(), + 1.into_process(&mut process), + ), + ( + Term::str_to_atom("b", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ( + Term::str_to_atom("c", DoNotCare).unwrap(), + 3.into_process(&mut process), + ), + ], + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_map_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::slice_to_map(&[], &mut process), true); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| { + Term::slice_to_map( + &[ + ( + Term::str_to_atom("b", DoNotCare).unwrap(), + 2.into_process(&mut process), + ), + ( + Term::str_to_atom("c", DoNotCare).unwrap(), + 3.into_process(&mut process), + ), + ], + &mut process, + ) + }, + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_small_integer_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_small_integer_left.rs new file mode 100644 index 000000000..d28ece711 --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_small_integer_left.rs @@ -0,0 +1,130 @@ +use super::*; + +#[test] +fn with_greater_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| (-1).into_process(&mut process), true); +} + +#[test] +fn with_same_small_integer_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true); +} + +#[test] +fn with_greater_small_integer_right_returns_false() { + is_greater_than_or_equal(|_, mut process| 1.into_process(&mut process), false); +} + +#[test] +fn with_greater_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MIN - 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_greater_big_integer_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + false, + ) +} + +#[test] +fn with_greater_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| (-1.0).into_process(&mut process), true) +} + +#[test] +fn with_same_value_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_greater_float_right_returns_false() { + is_greater_than_or_equal(|_, mut process| 1.0.into_process(&mut process), false) +} + +#[test] +fn with_atom_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), false); +} + +#[test] +fn with_local_reference_right_returns_false() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), false); +} + +#[test] +fn with_local_pid_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), false); +} + +#[test] +fn with_external_pid_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + false, + ); +} + +#[test] +fn with_tuple_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal(|mut process| 0.into_process(&mut process), right, expected); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_subbinary_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_subbinary_left.rs new file mode 100644 index 000000000..4b8d48244 --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_subbinary_left.rs @@ -0,0 +1,223 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_tuple_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[], &mut process), + true, + ); +} + +#[test] +fn with_map_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::slice_to_map(&[], &mut process), true); +} + +#[test] +fn with_empty_list_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, true); +} + +#[test] +fn with_list_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_prefix_heap_binary_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[1], &mut process), + true, + ); +} + +#[test] +fn with_same_length_heap_binary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[0], &mut process), + true, + ); +} + +#[test] +fn with_longer_heap_binary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[0, 1, 2], &mut process), + true, + ); +} + +#[test] +fn with_same_value_heap_binary_right_returns_true() { + super::is_greater_than_or_equal( + |mut process| { + let original = Term::slice_to_binary(&[1], &mut process); + Term::subbinary(original, 0, 0, 1, 0, &mut process) + }, + |_, mut process| Term::slice_to_binary(&[1], &mut process), + true, + ) +} + +#[test] +fn with_shorter_heap_binary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[2], &mut process), + false, + ); +} + +#[test] +fn with_heap_binary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[2, 1], &mut process), + false, + ); +} + +#[test] +fn with_heap_binary_with_greater_byte_than_bits_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[1, 0b1000_0000], &mut process), + false, + ); +} + +#[test] +fn with_prefix_subbinary_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[1], &mut process); + Term::subbinary(original, 0, 0, 1, 0, &mut process) + }, + true, + ); +} + +#[test] +fn with_same_length_subbinary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[0, 1], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + true, + ); +} + +#[test] +fn with_longer_subbinary_with_greater_byte_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| bitstring!(0, 1, 0b10 :: 2, &mut process), + true, + ); +} + +#[test] +fn with_same_subbinary_right_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_subbinary_right_returns_true() { + is_greater_than_or_equal(|_, mut process| bitstring!(1, 1 :: 2, &mut process), true); +} + +#[test] +fn with_shorter_subbinary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[2], &mut process); + Term::subbinary(original, 0, 0, 1, 0, &mut process) + }, + false, + ); +} + +#[test] +fn with_subbinary_with_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[2, 1], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + false, + ); +} + +#[test] +fn with_subbinary_with_different_greater_byte_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + let original = Term::slice_to_binary(&[1, 2], &mut process); + Term::subbinary(original, 0, 0, 2, 0, &mut process) + }, + false, + ); +} + +#[test] +fn with_subbinary_with_value_with_shorter_length_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1, 1 :: 1, &mut process), false) +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| bitstring!(1, 1 :: 2, &mut process), + right, + expected, + ); +} diff --git a/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_tuple_left.rs b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_tuple_left.rs new file mode 100644 index 000000000..3cfc9fa6e --- /dev/null +++ b/lumen_runtime/src/otp/erlang/tests/is_greater_than_or_equal_2/with_tuple_left.rs @@ -0,0 +1,167 @@ +use super::*; + +#[test] +fn with_small_integer_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.into_process(&mut process), true) +} + +#[test] +fn with_big_integer_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process), + true, + ) +} + +#[test] +fn with_float_right_returns_true() { + is_greater_than_or_equal(|_, mut process| 0.0.into_process(&mut process), true) +} + +#[test] +fn with_atom_returns_true() { + is_greater_than_or_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), true); +} + +#[test] +fn with_local_reference_right_returns_true() { + is_greater_than_or_equal(|_, mut process| Term::local_reference(&mut process), true); +} + +#[test] +fn with_local_pid_right_returns_true() { + is_greater_than_or_equal(|_, _| Term::local_pid(0, 1).unwrap(), true); +} + +#[test] +fn with_external_pid_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(), + true, + ); +} + +#[test] +fn with_smaller_tuple_right_returns_true() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_tuple(&[1.into_process(&mut process)], &mut process), + true, + ); +} + +#[test] +fn with_same_size_tuple_with_greater_elements_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_tuple( + &[1.into_process(&mut process), 1.into_process(&mut process)], + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_tuple_returns_true() { + is_greater_than_or_equal(|left, _| left, true); +} + +#[test] +fn with_same_value_tuple_returns_true() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_tuple( + &[1.into_process(&mut process), 2.into_process(&mut process)], + &mut process, + ) + }, + true, + ); +} + +#[test] +fn with_same_size_tuple_with_greater_elements_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_tuple( + &[1.into_process(&mut process), 3.into_process(&mut process)], + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_greater_size_tuple_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::slice_to_tuple( + &[ + 1.into_process(&mut process), + 2.into_process(&mut process), + 3.into_process(&mut process), + ], + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_map_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_map(&[], &mut process), + false, + ); +} + +#[test] +fn with_empty_list_right_returns_false() { + is_greater_than_or_equal(|_, _| Term::EMPTY_LIST, false); +} + +#[test] +fn with_list_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| { + Term::cons( + 0.into_process(&mut process), + 1.into_process(&mut process), + &mut process, + ) + }, + false, + ); +} + +#[test] +fn with_heap_binary_right_returns_false() { + is_greater_than_or_equal( + |_, mut process| Term::slice_to_binary(&[], &mut process), + false, + ); +} + +#[test] +fn with_subbinary_right_returns_false() { + is_greater_than_or_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false); +} + +fn is_greater_than_or_equal(right: R, expected: bool) +where + R: FnOnce(Term, &mut Process) -> Term, +{ + super::is_greater_than_or_equal( + |mut process| { + Term::slice_to_tuple( + &[1.into_process(&mut process), 2.into_process(&mut process)], + &mut process, + ) + }, + right, + expected, + ); +}