Skip to content

Commit

Permalink
Test Refactor (#29)
Browse files Browse the repository at this point in the history
* Added multiindex for #20

* Moved tests to separate module

---------

Co-authored-by: Alpo <[email protected]>
  • Loading branch information
crnbarr93 and AlpinYukseloglu authored Feb 17, 2024
1 parent d62d528 commit ca96a0e
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 259 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
pull_request:

env:
env:
CARGO_TERM_COLOR: always

jobs:
Expand All @@ -18,6 +18,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- run: cargo build --verbose
- run: cargo test --verbose

- run: rustup target add wasm32-unknown-unknown
- run: cargo wasm --verbose
- run: cargo unit-test --verbose
9 changes: 6 additions & 3 deletions contracts/orderbook/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
pub mod contract;
mod error;
pub mod msg;
pub mod types;
pub mod state;
mod orderbook;
mod order;
mod orderbook;
pub mod state;
pub mod types;

#[cfg(test)]
pub mod tests;

pub use crate::error::ContractError;
43 changes: 0 additions & 43 deletions contracts/orderbook/src/orderbook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,46 +29,3 @@ pub fn create_orderbook(
.add_attribute("method", "createOrderbook")
.add_attribute("book_id", book_id.to_string()))
}

#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};

#[test]
fn test_create_orderbook() {
let mut deps = mock_dependencies();
let env = mock_env();
let info = mock_info("creator", &[]);

// Attempt to create an orderbook
let quote_denom = "quote".to_string();
let base_denom = "base".to_string();
let create_response = create_orderbook(
deps.as_mut(),
env,
info,
quote_denom.clone(),
base_denom.clone(),
)
.unwrap();

// Verify response
let expected_book_id: u64 = 0;
assert_eq!(create_response.attributes[0], ("method", "createOrderbook"));
assert_eq!(
create_response.attributes[1],
("book_id", &expected_book_id.to_string())
);

// Verify orderbook is saved correctly
let orderbook = ORDERBOOKS
.load(deps.as_ref().storage, &expected_book_id)
.unwrap();
assert_eq!(orderbook.quote_denom, quote_denom);
assert_eq!(orderbook.base_denom, base_denom);
assert_eq!(orderbook.current_tick, 0);
assert_eq!(orderbook.next_bid_tick, MIN_TICK);
assert_eq!(orderbook.next_ask_tick, MAX_TICK);
}
}
209 changes: 0 additions & 209 deletions contracts/orderbook/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ pub fn new_order_id(storage: &mut dyn Storage) -> Result<u64, ContractError> {

// TODO: Add pagination
// TODO: How finite do we need queries?

/// Retrieves a list of `LimitOrder` filtered by the specified `FilterOwnerOrders`.
pub fn get_orders_by_owner(
storage: &dyn Storage,
Expand Down Expand Up @@ -104,211 +103,3 @@ pub fn get_orders_by_owner(
};
Ok(orders)
}

#[cfg(test)]
mod test {
use super::*;
use crate::types::OrderDirection;
use cosmwasm_std::testing::MockStorage;
use cosmwasm_std::{Addr, Order};

#[test]
fn test_new_orderbook_id() {
let mut storage = MockStorage::new();
let id = new_orderbook_id(&mut storage).unwrap();
assert_eq!(id, 0);
let id = new_orderbook_id(&mut storage).unwrap();
assert_eq!(id, 1);
}

#[test]
fn test_order_id_works() {
let mut storage = MockStorage::new();
let id = new_order_id(&mut storage).unwrap();
assert_eq!(id, 0);
let id = new_order_id(&mut storage).unwrap();
assert_eq!(id, 1);
}

#[test]
fn test_tick_iteration() {
let mut storage = MockStorage::new();
let book_id = new_orderbook_id(&mut storage).unwrap();
let tick_amount = 50;
for i in -tick_amount..tick_amount {
TICK_LIQUIDITY
.save(&mut storage, &(book_id, i), &Uint128::new(i as u128))
.unwrap();
}
let prefix = TICK_LIQUIDITY.prefix(book_id);
let ticks_asc: Vec<i64> = prefix
.keys(&storage, None, None, Order::Ascending)
.map(|result| result.unwrap())
.collect();
let ticks_desc: Vec<i64> = prefix
.keys(&storage, None, None, Order::Descending)
.map(|result| result.unwrap())
.collect();
for i in 0..tick_amount * 2 {
assert_eq!(ticks_asc[i as usize], -tick_amount + i);
assert_eq!(ticks_desc[i as usize], tick_amount - i - 1);
}
}

#[test]
fn test_order_iteration() {
let mut storage = MockStorage::new();
let order_amount = 50;
let book_id = new_orderbook_id(&mut storage).unwrap();
let tick = 0;
for i in 0..order_amount {
let order_id = new_order_id(&mut storage).unwrap();
let order = LimitOrder {
tick_id: tick,
book_id,
order_id,
owner: Addr::unchecked(format!("maker{i}")),
quantity: Uint128::new(i as u128),
order_direction: OrderDirection::Ask,
};
orders()
.save(&mut storage, &(book_id, tick, i), &order)
.unwrap();
}

let tick_orders = orders().prefix((book_id, tick));
let orders_desc: Vec<LimitOrder> = tick_orders
.range(&storage, None, None, Order::Descending)
.map(|result| result.unwrap().1)
.collect();
let orders_asc: Vec<LimitOrder> = tick_orders
.range(&storage, None, None, Order::Ascending)
.map(|result| result.unwrap().1)
.collect();
for i in 0..order_amount {
assert_eq!(orders_desc[i as usize].order_id, order_amount - i - 1);
assert_eq!(orders_asc[i as usize].order_id, i);
}
}

#[test]
fn test_get_orders_by_owner_all() {
let mut storage = MockStorage::new();
let order_amount = 10;
let owner = "owner1";

let book_ids: Vec<u64> = (0..3)
.map(|_| new_orderbook_id(&mut storage).unwrap())
.collect();

(0..order_amount).for_each(|i| {
let order_id = new_order_id(&mut storage).unwrap();
let other_owner = &format!("owner{i}");
let current_owner = Addr::unchecked(if i % 2 == 0 { owner } else { other_owner });
let order = LimitOrder::new(
book_ids[i % 3],
0,
order_id,
OrderDirection::Ask,
current_owner,
Uint128::new(i as u128),
);
orders()
.save(&mut storage, &(order.book_id, 0, i as u64), &order)
.unwrap();
});

let owner_orders: Vec<LimitOrder> =
get_orders_by_owner(&storage, FilterOwnerOrders::All(Addr::unchecked(owner))).unwrap();

assert_eq!(owner_orders.len(), order_amount / 2 + 1);
owner_orders.iter().for_each(|order| {
assert_eq!(order.owner, Addr::unchecked(owner));
});
}

#[test]
fn test_get_orders_by_owner_by_book() {
let mut storage = MockStorage::new();
let order_amount = 100;
let owner = "owner1";

// Generate three new book IDs
let book_ids: Vec<u64> = (0..3)
.map(|_| new_orderbook_id(&mut storage).unwrap())
.collect();

// Create orders alternating ownership between `owner` and dynamically generated owners amongst all books evenly
(0..order_amount).for_each(|i| {
let order_id = new_order_id(&mut storage).unwrap();
let other_owner = &format!("owner{i}");
let current_owner = Addr::unchecked(if i % 2 == 0 { owner } else { other_owner });
let order = LimitOrder::new(
book_ids[i % 3],
0,
order_id,
OrderDirection::Ask,
current_owner,
Uint128::new(i as u128),
);
orders()
.save(&mut storage, &(order.book_id, 0, i as u64), &order)
.unwrap();
});

// Verify orders by book ID
book_ids.iter().for_each(|&book_id| {
let owner_orders = get_orders_by_owner(
&storage,
FilterOwnerOrders::ByBook(book_id, Addr::unchecked(owner)),
)
.unwrap();
assert!(!owner_orders.is_empty());
owner_orders.iter().for_each(|order| {
assert_eq!(order.owner, Addr::unchecked(owner));
assert_eq!(order.book_id, book_id);
});
});
}

#[test]
fn test_get_orders_by_owner_by_tick() {
let mut storage = MockStorage::new();
let order_amount = 100;
let ticks = [0, 1, 2];
let owner = "owner1";
let book_id = new_orderbook_id(&mut storage).unwrap();

// Create orders alternating ownership between `owner` and dynamically generated owners amongst all ticks evenly
(0..order_amount).for_each(|i| {
let order_id = new_order_id(&mut storage).unwrap();
let other_owner = &format!("owner{i}");
let current_owner = Addr::unchecked(if i % 2 == 0 { owner } else { other_owner });
let tick = ticks[i % 3];
let order = LimitOrder::new(
book_id,
tick,
order_id,
OrderDirection::Ask,
current_owner,
Uint128::new(i as u128),
);
orders()
.save(&mut storage, &(book_id, tick, i as u64), &order)
.unwrap();
});

ticks.iter().for_each(|&tick| {
let owner_orders = get_orders_by_owner(
&storage,
FilterOwnerOrders::ByTick(book_id, tick, Addr::unchecked(owner)),
)
.unwrap();
assert!(!owner_orders.is_empty());
owner_orders.iter().for_each(|order| {
assert_eq!(order.owner, Addr::unchecked(owner));
assert_eq!(order.tick_id, tick);
});
});
}
}
2 changes: 2 additions & 0 deletions contracts/orderbook/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod test_orderbook;
pub mod test_state;
42 changes: 42 additions & 0 deletions contracts/orderbook/src/tests/test_orderbook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::{
orderbook::*,
state::{MAX_TICK, MIN_TICK, ORDERBOOKS},
};
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};

#[test]
fn test_create_orderbook() {
let mut deps = mock_dependencies();
let env = mock_env();
let info = mock_info("creator", &[]);

// Attempt to create an orderbook
let quote_denom = "quote".to_string();
let base_denom = "base".to_string();
let create_response = create_orderbook(
deps.as_mut(),
env,
info,
quote_denom.clone(),
base_denom.clone(),
)
.unwrap();

// Verify response
let expected_book_id: u64 = 0;
assert_eq!(create_response.attributes[0], ("method", "createOrderbook"));
assert_eq!(
create_response.attributes[1],
("book_id", &expected_book_id.to_string())
);

// Verify orderbook is saved correctly
let orderbook = ORDERBOOKS
.load(deps.as_ref().storage, &expected_book_id)
.unwrap();
assert_eq!(orderbook.quote_denom, quote_denom);
assert_eq!(orderbook.base_denom, base_denom);
assert_eq!(orderbook.current_tick, 0);
assert_eq!(orderbook.next_bid_tick, MIN_TICK);
assert_eq!(orderbook.next_ask_tick, MAX_TICK);
}
Loading

0 comments on commit ca96a0e

Please sign in to comment.