Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion acvm-repo/acir_field/src/generic_ark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub trait AcirField:
+ From<usize>
+ From<u128>
// + From<u64>
// + From<u32>
+ From<u32>
// + From<u16>
// + From<u8>
+ From<bool>
Expand Down Expand Up @@ -221,6 +221,12 @@ macro_rules! field_wrapper {
}
}

impl From<u32> for $wrapper {
fn from(value: u32) -> Self {
Self($field::from(value))
}
}

impl From<usize> for $wrapper {
fn from(value: usize) -> Self {
Self($field::from(value))
Expand Down
7 changes: 7 additions & 0 deletions noir_stdlib/src/test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ unconstrained fn set_mock_times_oracle(id: Field, times: u64) {}
#[oracle(clear_mock)]
unconstrained fn clear_mock_oracle(id: Field) {}

#[oracle(get_times_called)]
unconstrained fn get_times_mock_called(id: Field) -> Field {}

pub struct OracleMock {
id: Field,
}
Expand Down Expand Up @@ -47,4 +50,8 @@ impl OracleMock {
pub unconstrained fn clear(self) {
clear_mock_oracle(self.id);
}

pub unconstrained fn times_called(self) -> Field {
get_times_mock_called(self.id)
}
}
28 changes: 28 additions & 0 deletions test_programs/noir_test_success/mock_oracle/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,31 @@ fn test_mock_struct_field() {
assert_eq(20, struct_field(point, another_array));
}
}

#[test]
fn test_times_called() {
// Safety: testing context
unsafe {
let mock = OracleMock::mock("void_field").returns(10);
assert_eq(mock.times_called(), 0);

call_void_field_twice(mock, 0);

assert_eq(void_field(), 10);
assert_eq(void_field(), 10);
assert_eq(void_field(), 10);
assert_eq(void_field(), 10);
assert_eq(void_field(), 10);

call_void_field_twice(mock, 7);

assert_eq(mock.times_called(), 9);
}
}

unconstrained fn call_void_field_twice(mock: OracleMock, initial_times_called: Field) {
assert_eq(mock.times_called(), initial_times_called);
assert_eq(void_field(), 10);
assert_eq(void_field(), 10);
assert_eq(mock.times_called(), initial_times_called + 2);
}
13 changes: 13 additions & 0 deletions tooling/nargo/src/foreign_calls/mocker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct MockedCall<F> {
result: ForeignCallResult<F>,
/// How many times should this mock be called before it is removed
times_left: Option<u64>,
/// How many times this mock was actually called
times_called: u32,
}

impl<F> MockedCall<F> {
Expand All @@ -33,6 +35,7 @@ impl<F> MockedCall<F> {
last_called_params: None,
result: ForeignCallResult { values: vec![] },
times_left: None,
times_called: 0,
}
}
}
Expand Down Expand Up @@ -140,6 +143,13 @@ where
self.mocked_responses.retain(|response| response.id != id);
Ok(ForeignCallResult::default())
}
Some(ForeignCall::GetTimesCalled) => {
let (id, _) = Self::extract_mock_id(&foreign_call.inputs)?;
let mock =
self.find_mock_by_id(id).unwrap_or_else(|| panic!("Unknown mock id {}", id));
let times_called = mock.times_called;
Ok(ForeignCallResult::from(F::from(times_called)))
}
_ => {
let mock_response_position = self
.mocked_responses
Expand All @@ -159,6 +169,9 @@ where

let result = mock.result.values.clone();

// Update the total number of calls to the mock
mock.times_called += 1;

if let Some(times_left) = &mut mock.times_left {
*times_left -= 1;
if *times_left == 0 {
Expand Down
3 changes: 3 additions & 0 deletions tooling/nargo/src/foreign_calls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub enum ForeignCall {
SetMockReturns,
SetMockTimes,
ClearMock,
GetTimesCalled,
}

impl std::fmt::Display for ForeignCall {
Expand All @@ -50,6 +51,7 @@ impl ForeignCall {
ForeignCall::SetMockReturns => "set_mock_returns",
ForeignCall::SetMockTimes => "set_mock_times",
ForeignCall::ClearMock => "clear_mock",
ForeignCall::GetTimesCalled => "get_times_called",
}
}

Expand All @@ -62,6 +64,7 @@ impl ForeignCall {
"set_mock_returns" => Some(ForeignCall::SetMockReturns),
"set_mock_times" => Some(ForeignCall::SetMockTimes),
"clear_mock" => Some(ForeignCall::ClearMock),
"get_times_called" => Some(ForeignCall::GetTimesCalled),
_ => None,
}
}
Expand Down
Loading