1a0be06c3b
24 Plätze mit je bis zu 99 Gegenständen. Hinzufügen füllt zuerst vorhandene Stapel und meldet, was nicht passt; Entfernen nimmt alles oder nichts. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
126 lines
3.6 KiB
Rust
126 lines
3.6 KiB
Rust
use grovewright_core::codec::{DecodeError, Reader, Writer};
|
|
use grovewright_core::inventory::{
|
|
Inventory, ItemId, Stack, INVENTORY_SLOTS, ITEM_STONE, STACK_LIMIT,
|
|
};
|
|
|
|
const OTHER: ItemId = ItemId(2);
|
|
const CAPACITY: u32 = STACK_LIMIT * INVENTORY_SLOTS as u32;
|
|
|
|
#[test]
|
|
fn a_new_inventory_is_empty() {
|
|
let inventory = Inventory::new();
|
|
assert_eq!(inventory.slots().len(), INVENTORY_SLOTS);
|
|
assert!(inventory.slots().iter().all(Option::is_none));
|
|
assert_eq!(inventory.count(ITEM_STONE), 0);
|
|
assert_eq!(inventory.free_space(ITEM_STONE), CAPACITY);
|
|
assert_eq!(Inventory::default(), inventory);
|
|
}
|
|
|
|
#[test]
|
|
fn add_tops_up_a_stack_before_using_an_empty_slot() {
|
|
let mut inventory = Inventory::new();
|
|
assert_eq!(inventory.add(ITEM_STONE, 90), 0);
|
|
assert_eq!(inventory.add(OTHER, 5), 0);
|
|
assert_eq!(inventory.add(ITEM_STONE, 20), 0);
|
|
|
|
let stone = |count| {
|
|
Some(Stack {
|
|
item: ITEM_STONE,
|
|
count,
|
|
})
|
|
};
|
|
assert_eq!(inventory.slots()[0], stone(99));
|
|
assert_eq!(
|
|
inventory.slots()[1],
|
|
Some(Stack {
|
|
item: OTHER,
|
|
count: 5
|
|
})
|
|
);
|
|
assert_eq!(inventory.slots()[2], stone(11));
|
|
assert_eq!(inventory.count(ITEM_STONE), 110);
|
|
assert_eq!(inventory.count(OTHER), 5);
|
|
}
|
|
|
|
#[test]
|
|
fn add_reports_what_does_not_fit() {
|
|
let mut inventory = Inventory::new();
|
|
assert_eq!(inventory.add(ITEM_STONE, CAPACITY + 7), 7);
|
|
assert_eq!(inventory.count(ITEM_STONE), CAPACITY);
|
|
assert_eq!(inventory.free_space(ITEM_STONE), 0);
|
|
assert_eq!(inventory.free_space(OTHER), 0);
|
|
assert_eq!(inventory.add(OTHER, 1), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn free_space_counts_empty_slots_and_matching_stacks() {
|
|
let mut inventory = Inventory::new();
|
|
inventory.add(ITEM_STONE, 10);
|
|
inventory.add(OTHER, 1);
|
|
assert_eq!(
|
|
inventory.free_space(ITEM_STONE),
|
|
CAPACITY - STACK_LIMIT - 10
|
|
);
|
|
assert_eq!(inventory.free_space(OTHER), CAPACITY - STACK_LIMIT - 1);
|
|
}
|
|
|
|
#[test]
|
|
fn remove_takes_exactly_the_requested_amount() {
|
|
let mut inventory = Inventory::new();
|
|
inventory.add(ITEM_STONE, 150);
|
|
assert!(inventory.remove(ITEM_STONE, 60));
|
|
assert_eq!(inventory.count(ITEM_STONE), 90);
|
|
assert_eq!(
|
|
inventory.slots()[0],
|
|
Some(Stack {
|
|
item: ITEM_STONE,
|
|
count: 90
|
|
})
|
|
);
|
|
assert_eq!(inventory.slots()[1], None);
|
|
}
|
|
|
|
#[test]
|
|
fn remove_changes_nothing_when_too_few_are_present() {
|
|
let mut inventory = Inventory::new();
|
|
inventory.add(ITEM_STONE, 10);
|
|
let before = inventory.clone();
|
|
assert!(!inventory.remove(ITEM_STONE, 11));
|
|
assert!(!inventory.remove(OTHER, 1));
|
|
assert_eq!(inventory, before);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = "item id zero is reserved")]
|
|
fn the_reserved_item_id_cannot_be_added() {
|
|
Inventory::new().add(ItemId(0), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn an_inventory_survives_encoding() {
|
|
let mut inventory = Inventory::new();
|
|
inventory.add(ITEM_STONE, 120);
|
|
inventory.add(OTHER, 3);
|
|
let mut w = Writer::new();
|
|
inventory.encode(&mut w);
|
|
let bytes = w.into_bytes();
|
|
let mut r = Reader::new(&bytes);
|
|
assert_eq!(Inventory::decode(&mut r), Ok(inventory));
|
|
assert_eq!(r.finish(), Ok(()));
|
|
}
|
|
|
|
#[test]
|
|
fn decoding_rejects_impossible_stack_counts() {
|
|
for count in [0, STACK_LIMIT + 1] {
|
|
let mut w = Writer::new();
|
|
w.u16(ITEM_STONE.0);
|
|
w.u32(count);
|
|
let bytes = w.into_bytes();
|
|
assert_eq!(
|
|
Inventory::decode(&mut Reader::new(&bytes)),
|
|
Err(DecodeError::InvalidValue("stack count")),
|
|
"count {count}"
|
|
);
|
|
}
|
|
}
|