Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
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)
}
}
17 changes: 17 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,20 @@ 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);
Comment thread
TomAFrench marked this conversation as resolved.
assert_eq(mock.times_called(), 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);

assert_eq(mock.times_called(), 5);
Comment thread
jfecher marked this conversation as resolved.
Outdated
}
}
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: u128,
Comment thread
jfecher marked this conversation as resolved.
Outdated
}

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