Skip to content

Commit

Permalink
move tests from stdlib to test_programs, add github action to test-ru…
Browse files Browse the repository at this point in the history
…st-workspace to ensure zero stdlib tests
  • Loading branch information
michaeljklein committed Jul 25, 2024
1 parent 2adc6ac commit 095ef56
Show file tree
Hide file tree
Showing 24 changed files with 760 additions and 701 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/test-rust-workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ concurrency:
cancel-in-progress: true

jobs:
ban-noir-stdlib-tests:
name: Ensure zero tests in noir_stdlib
runs-on: ubuntu-latest
# We want this job to always run (even if the dependant jobs fail) as we want this job to fail rather than skipping.
if: ${{ always() }}

steps:
- name: Report overall success
run: |
&& echo 'failure: tests in the stdlib' || echo 'success: no tests in the stdlib'
if grep -r "\s*#\[test]" noir_stdlib; then
exit 1 # test found in noir_stdlib, fail
else
exit 0
fi
build-test-artifacts:
name: Build test artifacts
runs-on: ubuntu-latest
Expand Down
20 changes: 0 additions & 20 deletions noir_stdlib/src/cmp.nr
Original file line number Diff line number Diff line change
Expand Up @@ -346,23 +346,3 @@ pub fn max<T>(v1: T, v2: T) -> T where T: Ord {
pub fn min<T>(v1: T, v2: T) -> T where T: Ord {
if v1 > v2 { v2 } else { v1 }
}

mod cmp_tests {
use crate::cmp::{min, max};

#[test]
fn sanity_check_min() {
assert_eq(min(0 as u64, 1 as u64), 0);
assert_eq(min(0 as u64, 0 as u64), 0);
assert_eq(min(1 as u64, 1 as u64), 1);
assert_eq(min(255 as u8, 0 as u8), 0);
}

#[test]
fn sanity_check_max() {
assert_eq(max(0 as u64, 1 as u64), 1);
assert_eq(max(0 as u64, 0 as u64), 0);
assert_eq(max(1 as u64, 1 as u64), 1);
assert_eq(max(255 as u8, 0 as u8), 255);
}
}
159 changes: 0 additions & 159 deletions noir_stdlib/src/collections/bounded_vec.nr
Original file line number Diff line number Diff line change
Expand Up @@ -150,162 +150,3 @@ impl<T, let MaxLen: u32, let Len: u32> From<[T; Len]> for BoundedVec<T, MaxLen>
BoundedVec::from_array(array)
}
}

mod bounded_vec_tests {

mod get {
use crate::collections::bounded_vec::BoundedVec;

#[test(should_fail_with = "Attempted to read past end of BoundedVec")]
fn panics_when_reading_elements_past_end_of_vec() {
let vec: BoundedVec<Field, 5> = BoundedVec::new();

crate::println(vec.get(0));
}
}

mod set {
use crate::collections::bounded_vec::BoundedVec;

#[test]
fn set_updates_values_properly() {
let mut vec = BoundedVec::from_array([0, 0, 0, 0, 0]);

vec.set(0, 42);
assert_eq(vec.storage, [42, 0, 0, 0, 0]);

vec.set(1, 43);
assert_eq(vec.storage, [42, 43, 0, 0, 0]);

vec.set(2, 44);
assert_eq(vec.storage, [42, 43, 44, 0, 0]);

vec.set(1, 10);
assert_eq(vec.storage, [42, 10, 44, 0, 0]);

vec.set(0, 0);
assert_eq(vec.storage, [0, 10, 44, 0, 0]);
}

#[test(should_fail_with = "Attempted to write past end of BoundedVec")]
fn panics_when_writing_elements_past_end_of_vec() {
let mut vec: BoundedVec<Field, 5> = BoundedVec::new();
vec.set(0, 42);

// Need to use println to avoid DIE removing the write operation.
crate::println(vec.get(0));
}
}

mod map {
use crate::collections::bounded_vec::BoundedVec;

#[test]
fn applies_function_correctly() {
// docs:start:bounded-vec-map-example
let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);
let result = vec.map(|value| value * 2);
// docs:end:bounded-vec-map-example
let expected = BoundedVec::from_array([2, 4, 6, 8]);

assert_eq(result, expected);
}

#[test]
fn applies_function_that_changes_return_type() {
let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);
let result = vec.map(|value| (value * 2) as Field);
let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 4, 6, 8]);

assert_eq(result, expected);
}

#[test]
fn does_not_apply_function_past_len() {
let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);
let result = vec.map(|value| if value == 0 { 5 } else { value });
let expected = BoundedVec::from_array([5, 1]);

assert_eq(result, expected);
assert_eq(result.storage()[2], 0);
}
}

mod from_array {
use crate::collections::bounded_vec::BoundedVec;

#[test]
fn empty() {
let empty_array: [Field; 0] = [];
let bounded_vec = BoundedVec::from_array([]);

assert_eq(bounded_vec.max_len(), 0);
assert_eq(bounded_vec.len(), 0);
assert_eq(bounded_vec.storage(), empty_array);
}

#[test]
fn equal_len() {
let array = [1, 2, 3];
let bounded_vec = BoundedVec::from_array(array);

assert_eq(bounded_vec.max_len(), 3);
assert_eq(bounded_vec.len(), 3);
assert_eq(bounded_vec.storage(), array);
}

#[test]
fn max_len_greater_then_array_len() {
let array = [1, 2, 3];
let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from_array(array);

assert_eq(bounded_vec.max_len(), 10);
assert_eq(bounded_vec.len(), 3);
assert_eq(bounded_vec.storage()[0], 1);
assert_eq(bounded_vec.storage()[1], 2);
assert_eq(bounded_vec.storage()[2], 3);
}

#[test(should_fail_with="from array out of bounds")]
fn max_len_lower_then_array_len() {
let _: BoundedVec<Field, 2> = BoundedVec::from_array([0; 3]);
}
}

mod trait_from {
use crate::collections::bounded_vec::BoundedVec;

#[test]
fn simple() {
let array = [1, 2];
let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from(array);

assert_eq(bounded_vec.max_len(), 10);
assert_eq(bounded_vec.len(), 2);
assert_eq(bounded_vec.storage()[0], 1);
assert_eq(bounded_vec.storage()[1], 2);
}
}

mod trait_eq {
use crate::collections::bounded_vec::BoundedVec;

#[test]
fn empty_equality() {
let mut bounded_vec1: BoundedVec<Field, 3> = BoundedVec::new();
let mut bounded_vec2: BoundedVec<Field, 3> = BoundedVec::new();

assert_eq(bounded_vec1, bounded_vec2);
}

#[test]
fn inequality() {
let mut bounded_vec1: BoundedVec<Field, 3> = BoundedVec::new();
let mut bounded_vec2: BoundedVec<Field, 3> = BoundedVec::new();
bounded_vec1.push(1);
bounded_vec2.push(2);

assert(bounded_vec1 != bounded_vec2);
}
}
}
33 changes: 0 additions & 33 deletions noir_stdlib/src/collections/vec.nr
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,3 @@ impl<T> Vec<T> {
self.slice.len()
}
}

mod tests {
use crate::collections::vec::Vec;

#[test]
fn set_updates_values_properly() {
let mut vec = Vec { slice: &[0, 0, 0, 0, 0] };

vec.set(0, 42);
assert_eq(vec.slice, &[42, 0, 0, 0, 0]);

vec.set(1, 43);
assert_eq(vec.slice, &[42, 43, 0, 0, 0]);

vec.set(2, 44);
assert_eq(vec.slice, &[42, 43, 44, 0, 0]);

vec.set(1, 10);
assert_eq(vec.slice, &[42, 10, 44, 0, 0]);

vec.set(0, 0);
assert_eq(vec.slice, &[0, 10, 44, 0, 0]);
}

#[test(should_fail)]
fn panics_when_writing_elements_past_end_of_vec() {
let mut vec = Vec::new();
vec.set(0, 42);

// Need to use println to avoid DIE removing the write operation.
crate::println(vec.get(0));
}
}
99 changes: 0 additions & 99 deletions noir_stdlib/src/field/bn254.nr
Original file line number Diff line number Diff line change
Expand Up @@ -133,102 +133,3 @@ pub fn gt(a: Field, b: Field) -> bool {
pub fn lt(a: Field, b: Field) -> bool {
gt(b, a)
}

mod tests {
// TODO: Allow imports from "super"
use crate::field::bn254::{decompose_hint, decompose, compute_lt, assert_gt, gt, lt, TWO_POW_128, compute_lte, PLO, PHI};

#[test]
fn check_decompose() {
assert_eq(decompose(TWO_POW_128), (0, 1));
assert_eq(decompose(TWO_POW_128 + 0x1234567890), (0x1234567890, 1));
assert_eq(decompose(0x1234567890), (0x1234567890, 0));
}

#[test]
unconstrained fn check_decompose_unconstrained() {
assert_eq(decompose(TWO_POW_128), (0, 1));
assert_eq(decompose(TWO_POW_128 + 0x1234567890), (0x1234567890, 1));
assert_eq(decompose(0x1234567890), (0x1234567890, 0));
}

#[test]
fn check_compute_lt() {
assert(compute_lt(0, 1, 16));
assert(compute_lt(0, 0x100, 16));
assert(compute_lt(0x100, TWO_POW_128 - 1, 16));
assert(!compute_lt(0, TWO_POW_128, 16));
}

#[test]
fn check_compute_lte() {
assert(compute_lte(0, 1, 16));
assert(compute_lte(0, 0x100, 16));
assert(compute_lte(0x100, TWO_POW_128 - 1, 16));
assert(!compute_lte(0, TWO_POW_128, 16));

assert(compute_lte(0, 0, 16));
assert(compute_lte(0x100, 0x100, 16));
assert(compute_lte(TWO_POW_128 - 1, TWO_POW_128 - 1, 16));
assert(compute_lte(TWO_POW_128, TWO_POW_128, 16));
}

#[test]
fn check_assert_gt() {
assert_gt(1, 0);
assert_gt(0x100, 0);
assert_gt((0 - 1), (0 - 2));
assert_gt(TWO_POW_128, 0);
assert_gt(0 - 1, 0);
}

#[test]
unconstrained fn check_assert_gt_unconstrained() {
assert_gt(1, 0);
assert_gt(0x100, 0);
assert_gt((0 - 1), (0 - 2));
assert_gt(TWO_POW_128, 0);
assert_gt(0 - 1, 0);
}

#[test]
fn check_gt() {
assert(gt(1, 0));
assert(gt(0x100, 0));
assert(gt((0 - 1), (0 - 2)));
assert(gt(TWO_POW_128, 0));
assert(!gt(0, 0));
assert(!gt(0, 0x100));
assert(gt(0 - 1, 0 - 2));
assert(!gt(0 - 2, 0 - 1));
}

#[test]
unconstrained fn check_gt_unconstrained() {
assert(gt(1, 0));
assert(gt(0x100, 0));
assert(gt((0 - 1), (0 - 2)));
assert(gt(TWO_POW_128, 0));
assert(!gt(0, 0));
assert(!gt(0, 0x100));
assert(gt(0 - 1, 0 - 2));
assert(!gt(0 - 2, 0 - 1));
}

#[test]
fn check_plo_phi() {
assert_eq(PLO + PHI * TWO_POW_128, 0);
let p_bytes = crate::field::modulus_le_bytes();
let mut p_low: Field = 0;
let mut p_high: Field = 0;

let mut offset = 1;
for i in 0..16 {
p_low += (p_bytes[i] as Field) * offset;
p_high += (p_bytes[i + 16] as Field) * offset;
offset *= 256;
}
assert_eq(p_low, PLO);
assert_eq(p_high, PHI);
}
}
35 changes: 0 additions & 35 deletions noir_stdlib/src/hash/keccak.nr
Original file line number Diff line number Diff line change
Expand Up @@ -104,38 +104,3 @@ pub(crate) fn keccak256<let N: u32>(mut input: [u8; N], message_size: u32) -> [u
}
result
}

mod tests {
use crate::hash::keccak::keccak256;

#[test]
fn smoke_test() {
let input = [0xbd];
let result = [
0x5a, 0x50, 0x2f, 0x9f, 0xca, 0x46, 0x7b, 0x26, 0x6d, 0x5b, 0x78, 0x33, 0x65, 0x19, 0x37, 0xe8, 0x05, 0x27, 0x0c, 0xa3, 0xf3, 0xaf, 0x1c, 0x0d, 0xd2, 0x46, 0x2d, 0xca, 0x4b, 0x3b, 0x1a, 0xbf
];
assert_eq(keccak256(input, input.len()), result);
}

#[test]
fn hash_hello_world() {
// "hello world"
let input = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
let result = [
0xec, 0xd0, 0xe1, 0x8, 0xa9, 0x8e, 0x19, 0x2a, 0xf1, 0xd2, 0xc2, 0x50, 0x55, 0xf4, 0xe3, 0xbe, 0xd7, 0x84, 0xb5, 0xc8, 0x77, 0x20, 0x4e, 0x73, 0x21, 0x9a, 0x52, 0x3, 0x25, 0x1f, 0xea, 0xab
];
assert_eq(keccak256(input, input.len()), result);
}

#[test]
fn var_size_hash() {
let input = [
189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
];
let result = [
226, 37, 115, 94, 94, 196, 72, 116, 194, 105, 79, 233, 65, 12, 30, 94, 181, 131, 170, 219, 171, 166, 236, 88, 143, 67, 255, 160, 248, 214, 39, 129
];
assert_eq(keccak256(input, 13), result);
}
}

Loading

0 comments on commit 095ef56

Please sign in to comment.