Skip to content

Commit

Permalink
=:=/2
Browse files Browse the repository at this point in the history
Map Erlang's "exactly equal" to "erlang::are_exactly_equal_2", which
then calls Rust's `eq`.
  • Loading branch information
KronicDeth committed Apr 15, 2019
1 parent 7a163c5 commit 2deaead
Show file tree
Hide file tree
Showing 16 changed files with 1,516 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lumen_runtime/src/otp/erlang.rs
Expand Up @@ -116,6 +116,11 @@ pub fn append_element_2(tuple: Term, element: Term, mut process: &mut Process) -
Ok(new_tuple.into())
}

/// `=:=/2` infix operator. Unlike `==`, does not convert between floats and integers.
pub fn are_exactly_equal_2(left: Term, right: Term) -> Term {
left.eq(&right).into()
}

pub fn atom_to_binary_2(atom: Term, encoding: Term, mut process: &mut Process) -> Result {
if atom.tag() == Atom {
encoding.atom_to_encoding()?;
Expand Down
1 change: 1 addition & 0 deletions lumen_runtime/src/otp/erlang/tests.rs
Expand Up @@ -11,6 +11,7 @@ mod add_2;
mod and_2;
mod andalso_2;
mod append_element_2;
mod are_exactly_equal_2;
mod atom_to_binary_2;
mod atom_to_list_1;
mod band_2;
Expand Down
25 changes: 25 additions & 0 deletions lumen_runtime/src/otp/erlang/tests/are_exactly_equal_2.rs
@@ -0,0 +1,25 @@
use super::*;

mod with_atom_left;
mod with_empty_list_left;
mod with_external_pid_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_subbinary_left;
mod with_tuple_left;

fn are_exactly_equal<L, R>(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::are_exactly_equal_2(left, right), expected.into());
});
}
@@ -0,0 +1,111 @@
use super::*;

#[test]
fn with_same_atom_returns_true() {
are_exactly_equal(|left, _| left, true);
}

#[test]
fn with_same_atom_value_returns_true() {
are_exactly_equal(|_, _| Term::str_to_atom("left", DoNotCare).unwrap(), true);
}

#[test]
fn with_different_atom_returns_false() {
are_exactly_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), false);
}

#[test]
fn with_local_reference_right_returns_false() {
are_exactly_equal(|_, mut process| Term::local_reference(&mut process), false);
}

#[test]
fn with_empty_list_right_returns_false() {
are_exactly_equal(|_, _| Term::EMPTY_LIST, false);
}

#[test]
fn with_list_right_returns_false() {
are_exactly_equal(
|_, mut process| {
Term::cons(
0.into_process(&mut process),
1.into_process(&mut process),
&mut process,
)
},
false,
);
}

#[test]
fn with_small_integer_right_returns_false() {
are_exactly_equal(|_, mut process| 0.into_process(&mut process), false)
}

#[test]
fn with_big_integer_right_returns_false() {
are_exactly_equal(
|_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process),
false,
)
}

#[test]
fn with_float_right_returns_false() {
are_exactly_equal(|_, mut process| 0.0.into_process(&mut process), false)
}

#[test]
fn with_local_pid_right_returns_false() {
are_exactly_equal(|_, _| Term::local_pid(0, 1).unwrap(), false);
}

#[test]
fn with_external_pid_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(),
false,
);
}

#[test]
fn with_tuple_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_tuple(&[], &mut process),
false,
);
}

#[test]
fn with_map_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_map(&[], &mut process),
false,
);
}

#[test]
fn with_heap_binary_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_binary(&[], &mut process),
false,
);
}

#[test]
fn with_subbinary_right_returns_false() {
are_exactly_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false);
}

fn are_exactly_equal<R>(right: R, expected: bool)
where
R: FnOnce(Term, &mut Process) -> Term,
{
super::are_exactly_equal(
|_| Term::str_to_atom("left", DoNotCare).unwrap(),
right,
expected,
);
}
@@ -0,0 +1,123 @@
use super::*;
use std::convert::Into;

#[test]
fn with_atom_returns_false() {
are_exactly_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), false);
}

#[test]
fn with_local_reference_right_returns_false() {
are_exactly_equal(|_, mut process| Term::local_reference(&mut process), false);
}

#[test]
fn with_empty_list_right_returns_false() {
are_exactly_equal(|_, _| Term::EMPTY_LIST, false);
}

#[test]
fn with_list_right_returns_false() {
are_exactly_equal(
|_, mut process| {
Term::cons(
0.into_process(&mut process),
1.into_process(&mut process),
&mut process,
)
},
false,
);
}

#[test]
fn with_small_integer_right_returns_false() {
are_exactly_equal(|_, mut process| 0.into_process(&mut process), false)
}

#[test]
fn with_same_big_integer_right_returns_true() {
are_exactly_equal(
|left, _| left,
true,
)
}

#[test]
fn with_same_value_big_integer_right_returns_true() {
are_exactly_equal(
|_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process),
true,
)
}

#[test]
fn with_different_big_integer_right_returns_false() {
are_exactly_equal(
|_, mut process| (crate::integer::small::MIN - 1).into_process(&mut process),
false,
)
}

#[test]
fn with_same_value_float_right_returns_false() {
are_exactly_equal(|_, mut process| ((crate::integer::small::MAX + 1) as f64).into_process(&mut process), false)
}

#[test]
fn with_different_value_float_right_returns_false() {
are_exactly_equal(|_, mut process| 1.0.into_process(&mut process), false)
}

#[test]
fn with_local_pid_right_returns_false() {
are_exactly_equal(|_, _| Term::local_pid(0, 1).unwrap(), false);
}

#[test]
fn with_external_pid_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(),
false,
);
}

#[test]
fn with_tuple_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_tuple(&[], &mut process),
false,
);
}

#[test]
fn with_map_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_map(&[], &mut process),
false,
);
}

#[test]
fn with_heap_binary_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_binary(&[], &mut process),
false,
);
}

#[test]
fn with_subbinary_right_returns_false() {
are_exactly_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false);
}

fn are_exactly_equal<R>(right: R, expected: bool)
where
R: FnOnce(Term, &mut Process) -> Term,
{
super::are_exactly_equal(
|mut process| 0.into_process(&mut process),
right,
expected,
);
}
@@ -0,0 +1,97 @@
use super::*;

#[test]
fn with_atom_right_returns_false() {
are_exactly_equal(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), false)
}

#[test]
fn with_local_reference_right_returns_false() {
are_exactly_equal(|_, mut process| Term::local_reference(&mut process), false);
}

#[test]
fn with_empty_list_right_returns_true() {
are_exactly_equal(|_, _| Term::EMPTY_LIST, true);
}

#[test]
fn with_list_right_returns_false() {
are_exactly_equal(
|_, mut process| {
Term::cons(
0.into_process(&mut process),
1.into_process(&mut process),
&mut process,
)
},
false,
);
}

#[test]
fn with_small_integer_right_returns_false() {
are_exactly_equal(|_, mut process| 0.into_process(&mut process), false)
}

#[test]
fn with_big_integer_right_returns_false() {
are_exactly_equal(
|_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process),
false,
)
}

#[test]
fn with_float_right_returns_false() {
are_exactly_equal(|_, mut process| 0.0.into_process(&mut process), false)
}

#[test]
fn with_local_pid_right_returns_false() {
are_exactly_equal(|_, _| Term::local_pid(0, 1).unwrap(), false);
}

#[test]
fn with_external_pid_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(),
false,
);
}

#[test]
fn with_tuple_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_tuple(&[], &mut process),
false,
);
}

#[test]
fn with_map_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_map(&[], &mut process),
false,
);
}

#[test]
fn with_heap_binary_right_returns_false() {
are_exactly_equal(
|_, mut process| Term::slice_to_binary(&[], &mut process),
false,
);
}

#[test]
fn with_subbinary_right_returns_false() {
are_exactly_equal(|_, mut process| bitstring!(1 :: 1, &mut process), false);
}

fn are_exactly_equal<R>(right: R, expected: bool)
where
R: FnOnce(Term, &mut Process) -> Term,
{
super::are_exactly_equal(|_| Term::EMPTY_LIST, right, expected);
}

0 comments on commit 2deaead

Please sign in to comment.