mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
impl integer tester trait and macro. test u32
This commit is contained in:
parent
31d2542d52
commit
c5868b430a
@ -366,7 +366,7 @@ impl Integer {
|
||||
let result = left_u8.div(
|
||||
cs.ns(|| {
|
||||
format!(
|
||||
"enforce {} / {}",
|
||||
"enforce {} ÷ {}",
|
||||
left_u8.value.unwrap(),
|
||||
right_u8.value.unwrap()
|
||||
)
|
||||
@ -379,7 +379,7 @@ impl Integer {
|
||||
let result = left_u16.div(
|
||||
cs.ns(|| {
|
||||
format!(
|
||||
"enforce {} / {}",
|
||||
"enforce {} ÷ {}",
|
||||
left_u16.value.unwrap(),
|
||||
right_u16.value.unwrap()
|
||||
)
|
||||
@ -392,7 +392,7 @@ impl Integer {
|
||||
let result = left_u32.div(
|
||||
cs.ns(|| {
|
||||
format!(
|
||||
"enforce {} / {}",
|
||||
"enforce {} ÷ {}",
|
||||
left_u32.value.unwrap(),
|
||||
right_u32.value.unwrap()
|
||||
)
|
||||
@ -405,7 +405,7 @@ impl Integer {
|
||||
let result = left_u64.div(
|
||||
cs.ns(|| {
|
||||
format!(
|
||||
"enforce {} / {}",
|
||||
"enforce {} ÷ {}",
|
||||
left_u64.value.unwrap(),
|
||||
right_u64.value.unwrap()
|
||||
)
|
||||
@ -418,7 +418,7 @@ impl Integer {
|
||||
let result = left_u128.div(
|
||||
cs.ns(|| {
|
||||
format!(
|
||||
"enforce {} / {}",
|
||||
"enforce {} ÷ {}",
|
||||
left_u128.value.unwrap(),
|
||||
right_u128.value.unwrap()
|
||||
)
|
||||
@ -428,7 +428,7 @@ impl Integer {
|
||||
Integer::U128(result)
|
||||
}
|
||||
(left, right) => {
|
||||
return Err(IntegerError::CannotEnforce(format!("{} / {}", left, right)))
|
||||
return Err(IntegerError::CannotEnforce(format!("{} ÷ {}", left, right)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
146
compiler/tests/integer/macros.rs
Normal file
146
compiler/tests/integer/macros.rs
Normal file
@ -0,0 +1,146 @@
|
||||
macro_rules! test_uint {
|
||||
($name: ident, $_type: ty, $gadget: ty, $directory: expr) => {
|
||||
pub struct $name {}
|
||||
|
||||
impl $name {
|
||||
fn test_min(min: $_type) {
|
||||
let min_allocated = <$gadget>::constant(min);
|
||||
|
||||
let program = compile_program($directory, "min.leo").unwrap();
|
||||
|
||||
output_expected_allocated(program, min_allocated);
|
||||
}
|
||||
|
||||
fn test_max(max: $_type) {
|
||||
let max_allocated = <$gadget>::constant(max);
|
||||
|
||||
let program = compile_program($directory, "max.leo").unwrap();
|
||||
|
||||
output_expected_allocated(program, max_allocated);
|
||||
}
|
||||
}
|
||||
|
||||
impl IntegerTester for $name {
|
||||
fn test_input() {
|
||||
// valid input
|
||||
let num: $_type = rand::random();
|
||||
let expected = <$gadget>::constant(num);
|
||||
|
||||
let mut program = compile_program($directory, "input.leo").unwrap();
|
||||
program.set_inputs(vec![Some(InputValue::Integer(num as usize))]);
|
||||
|
||||
output_expected_allocated(program, expected);
|
||||
|
||||
// invalid input
|
||||
let mut program = compile_program($directory, "input.leo").unwrap();
|
||||
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
fail_integer(program);
|
||||
|
||||
// None input
|
||||
let mut program = compile_program($directory, "input.leo").unwrap();
|
||||
program.set_inputs(vec![None]);
|
||||
fail_synthesis(program);
|
||||
}
|
||||
|
||||
fn test_add() {
|
||||
for _ in 0..10 {
|
||||
let r1: $_type = rand::random();
|
||||
let r2: $_type = rand::random();
|
||||
|
||||
let sum = r1.wrapping_add(r2);
|
||||
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "add.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as usize)),
|
||||
Some(InputValue::Integer(r2 as usize)),
|
||||
]);
|
||||
|
||||
output_expected_allocated(program, sum_allocated);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_sub() {
|
||||
for _ in 0..10 {
|
||||
let r1: $_type = rand::random();
|
||||
let r2: $_type = rand::random();
|
||||
|
||||
let sum = r1.wrapping_sub(r2);
|
||||
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "sub.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as usize)),
|
||||
Some(InputValue::Integer(r2 as usize)),
|
||||
]);
|
||||
|
||||
output_expected_allocated(program, sum_allocated);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_mul() {
|
||||
for _ in 0..10 {
|
||||
let r1: $_type = rand::random();
|
||||
let r2: $_type = rand::random();
|
||||
|
||||
let sum = r1.wrapping_mul(r2);
|
||||
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "mul.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as usize)),
|
||||
Some(InputValue::Integer(r2 as usize)),
|
||||
]);
|
||||
|
||||
output_expected_allocated(program, sum_allocated);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_div() {
|
||||
for _ in 0..10 {
|
||||
let r1: $_type = rand::random();
|
||||
let r2: $_type = rand::random();
|
||||
|
||||
let sum = r1.wrapping_div(r2);
|
||||
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "div.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as usize)),
|
||||
Some(InputValue::Integer(r2 as usize)),
|
||||
]);
|
||||
|
||||
output_expected_allocated(program, sum_allocated);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_pow() {
|
||||
for _ in 0..10 {
|
||||
let r1: $_type = rand::random();
|
||||
let r2: $_type = rand::random();
|
||||
|
||||
let sum = r1.wrapping_pow(r2);
|
||||
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "pow.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as usize)),
|
||||
Some(InputValue::Integer(r2 as usize)),
|
||||
]);
|
||||
|
||||
output_expected_allocated(program, sum_allocated);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1 +1,26 @@
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
pub use self::macros::*;
|
||||
|
||||
pub trait IntegerTester {
|
||||
/// Tests use of the integer in a function input
|
||||
fn test_input();
|
||||
|
||||
/// Tests a wrapping addition
|
||||
fn test_add();
|
||||
|
||||
/// Tests a wrapping subtraction
|
||||
fn test_sub();
|
||||
|
||||
/// Tests a wrapping multiplication
|
||||
fn test_mul();
|
||||
|
||||
/// Tests a non-wrapping division
|
||||
fn test_div();
|
||||
|
||||
/// Tests a wrapping exponentiation
|
||||
fn test_pow();
|
||||
}
|
||||
|
||||
// must be below macro definitions!
|
||||
pub mod u32;
|
||||
|
@ -1,4 +0,0 @@
|
||||
// This program should panic at compilation.
|
||||
function main() -> u32 {
|
||||
return 1 - 2
|
||||
}
|
3
compiler/tests/integer/u32/add.leo
Normal file
3
compiler/tests/integer/u32/add.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: u32, b: u32) -> u32 {
|
||||
return a + b
|
||||
}
|
3
compiler/tests/integer/u32/div.leo
Normal file
3
compiler/tests/integer/u32/div.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: u32, b: u32) -> u32 {
|
||||
return a / b
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() -> u32 {
|
||||
return 1 - 1
|
||||
}
|
||||
return 4294967295
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main() -> u32 {
|
||||
return 1 + 1
|
||||
}
|
||||
return 0
|
||||
}
|
@ -1,14 +1,31 @@
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use crate::{
|
||||
compile_program, get_error, get_output, integer::IntegerTester, EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FunctionError, IntegerError},
|
||||
types::Integer,
|
||||
ConstrainedValue, InputValue,
|
||||
};
|
||||
|
||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt32};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integer/u32/";
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
|
||||
let output = get_output(program);
|
||||
|
||||
match output {
|
||||
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
|
||||
[ConstrainedValue::Integer(Integer::U32(actual))] => assert_eq!(*actual, expected),
|
||||
_ => panic!("program output unknown return value"),
|
||||
},
|
||||
_ => panic!("program output unknown return value"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn output_zero(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
@ -31,17 +48,6 @@ pub(crate) fn output_one(program: EdwardsTestCompiler) {
|
||||
)
|
||||
}
|
||||
|
||||
fn output_two(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(2u32)
|
||||
))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn fail_integer(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
@ -61,17 +67,19 @@ fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_u32_bool() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_u32.leo").unwrap();
|
||||
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
fail_integer(program);
|
||||
}
|
||||
fn test_u32() {
|
||||
test_uint!(TestU32, u32, UInt32, DIRECTORY_NAME);
|
||||
|
||||
#[test]
|
||||
fn test_input_u32_none() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_u32.leo").unwrap();
|
||||
program.set_inputs(vec![None]);
|
||||
fail_synthesis(program);
|
||||
TestU32::test_min(std::u32::MIN);
|
||||
TestU32::test_max(std::u32::MAX);
|
||||
|
||||
TestU32::test_input();
|
||||
|
||||
TestU32::test_add();
|
||||
// TestU32::test_sub(); //Todo: Catch subtraction overflow error in gadget
|
||||
TestU32::test_mul();
|
||||
TestU32::test_div();
|
||||
TestU32::test_pow();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -85,22 +93,3 @@ fn test_one() {
|
||||
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_1_plus_1() {
|
||||
let program = compile_program(DIRECTORY_NAME, "1+1.leo").unwrap();
|
||||
output_two(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_1_minus_1() {
|
||||
let program = compile_program(DIRECTORY_NAME, "1-1.leo").unwrap();
|
||||
output_zero(program)
|
||||
}
|
||||
|
||||
// #[test] // Todo: Catch subtraction overflow error in gadget
|
||||
// fn test_1_minus_2() {
|
||||
// let program = compile_program(DIRECTORY_NAME, "1-2.leo").unwrap();
|
||||
// let error = get_error(program);
|
||||
// println!("{}", error);
|
||||
// }
|
||||
|
3
compiler/tests/integer/u32/mul.leo
Normal file
3
compiler/tests/integer/u32/mul.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: u32, b: u32) -> u32 {
|
||||
return a * b
|
||||
}
|
3
compiler/tests/integer/u32/pow.leo
Normal file
3
compiler/tests/integer/u32/pow.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: u32, b: u32) -> u32 {
|
||||
return a ** b
|
||||
}
|
3
compiler/tests/integer/u32/sub.leo
Normal file
3
compiler/tests/integer/u32/sub.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: u32, b: u32) -> u32 {
|
||||
return a - b
|
||||
}
|
Loading…
Reference in New Issue
Block a user