mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 21:17:03 +00:00
412 lines
12 KiB
Plaintext
412 lines
12 KiB
Plaintext
@import <Foundation/CPCache.j>
|
|
|
|
|
|
/*
|
|
* CPCacheTest tests all methods from CPCache
|
|
*/
|
|
@implementation CPCacheTest : OJTestCase<CPCacheDelegate>
|
|
{
|
|
// Parameters to check delegate
|
|
int _countDelegateExecuted;
|
|
CPArray _caches;
|
|
CPArray _objects;
|
|
}
|
|
|
|
- (void)setUp
|
|
{
|
|
// Initialize data to check delegate
|
|
_countDelegateExecuted = 0;
|
|
_caches = [[CPArray alloc] init];
|
|
_objects = [[CPArray alloc] init];
|
|
}
|
|
|
|
|
|
/*
|
|
* Delegate method, called when an object is evicted
|
|
*/
|
|
- (void)cache:(CPCache)cache willEvictObject:(id)obj
|
|
{
|
|
_countDelegateExecuted++;
|
|
[_caches addObject:cache];
|
|
[_objects addObject:obj];
|
|
}
|
|
|
|
|
|
/*
|
|
* Tests methods of CPCache
|
|
*/
|
|
- (void)testInit
|
|
{
|
|
var cache = [[CPCache alloc] init];
|
|
|
|
// Private attributes
|
|
[self assert:CPCache equals:[cache class]];
|
|
[self assert:CPDictionary equals:[cache._items class]];
|
|
[self assert:0 equals:cache._currentPosition];
|
|
[self assert:-1 equals:cache._totalCostCache];
|
|
[self assert:0 equals:cache._implementedDelegateMethods];
|
|
|
|
// Public attributes
|
|
[self assert:@"" equals:[cache name]];
|
|
[self assert:0 equals:[cache countLimit]];
|
|
[self assert:0 equals:[cache totalCostLimit]];
|
|
[self assert:nil equals:[cache delegate]];
|
|
}
|
|
|
|
- (void)testObjectForKey
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
|
|
// With valid key
|
|
[self assert:@"Object1" equals:[cache objectForKey:@"key1"]];
|
|
|
|
// With invalid key
|
|
[self assert:nil equals:[cache objectForKey:@"key666"]];
|
|
|
|
// With nil key
|
|
[self assert:nil equals:[cache objectForKey:nil]];
|
|
}
|
|
|
|
- (void)testSetObjectForKeyDefault
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
|
|
// Check result when add key in empty cache
|
|
[cache setObject:@"Object1" forKey:@"key1"]
|
|
[self assert:@"Object1" equals:[cache objectForKey:@"key1"]];
|
|
|
|
// Check delegate
|
|
[self assert:0 equals:_countDelegateExecuted];
|
|
[self assert:0 equals:[_caches count]];
|
|
[self assert:0 equals:[_objects count]];
|
|
}
|
|
|
|
- (void)testSetObjectForKeyWithExistingKey
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
[cache setObject:@"Object2" forKey:@"key2"];
|
|
|
|
// Check result when add object with existing key in cache
|
|
[cache setObject:@"Object3" forKey:@"key1"];
|
|
[self assert:@"Object3" equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
}
|
|
|
|
- (void)testSetObjectForKeyDiscardByCost
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setTotalCostLimit:100];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:50];
|
|
|
|
// Check result when add key in cache with total cost limit
|
|
[cache setObject:@"Object3" forKey:@"key3" cost:1];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
[self assert:@"Object3" equals:[cache objectForKey:@"key3"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
}
|
|
|
|
- (void)testSetObjectForKeyDiscardByCount
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setCountLimit:2];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
[cache setObject:@"Object2" forKey:@"key2"];
|
|
|
|
// Check result when add key in cache with count limit
|
|
[cache setObject:@"Object3" forKey:@"key3"];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
[self assert:@"Object3" equals:[cache objectForKey:@"key3"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
}
|
|
|
|
- (void)testRemoveObjectForKey
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
|
|
// Remove object
|
|
[cache removeObjectForKey:@"key1"];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
}
|
|
|
|
- (void)testRemoveAllObjects
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
[cache setObject:@"Object2" forKey:@"key2"];
|
|
|
|
// Remove all objects
|
|
[cache removeAllObjects];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:nil equals:[cache objectForKey:@"key2"]];
|
|
|
|
// Check delegate
|
|
[self assert:2 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
[self assert:cache equals:[_caches objectAtIndex:1]];
|
|
[self assert:@"Object2" equals:[_objects objectAtIndex:1]];
|
|
}
|
|
|
|
|
|
/*
|
|
* Accessors and mutators
|
|
*/
|
|
|
|
- (void)testSetCountLimit
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
[cache setObject:@"Object2" forKey:@"key2"];
|
|
[cache setObject:@"Object3" forKey:@"key3"];
|
|
|
|
// Set count limit
|
|
[cache setCountLimit:2];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
[self assert:@"Object3" equals:[cache objectForKey:@"key3"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
|
|
// Check new count limit
|
|
[self assert:2 equals:[cache countLimit]];
|
|
}
|
|
|
|
- (void)testSetTotalCostLimit
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:10];
|
|
[cache setObject:@"Object3" forKey:@"key3" cost:70];
|
|
|
|
// Set total cost limit
|
|
[cache setTotalCostLimit:100];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
[self assert:@"Object3" equals:[cache objectForKey:@"key3"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
|
|
// Check total cost limit
|
|
[self assert:100 equals:[cache totalCostLimit]];
|
|
}
|
|
|
|
- (void)testSetDelegate
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setDelegate:self];
|
|
|
|
[self assert:self equals:[cache delegate]];
|
|
[self assert:(1 << 1) equals:cache._implementedDelegateMethods]
|
|
}
|
|
|
|
/*
|
|
* Test private methods
|
|
*/
|
|
|
|
- (void)testCount
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:10];
|
|
[cache setObject:@"Object3" forKey:@"key3" cost:70];
|
|
|
|
[self assert:3 equals:[cache _count]];
|
|
}
|
|
|
|
- (void)testTotalCost
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:10];
|
|
[cache setObject:@"Object3" forKey:@"key3" cost:70];
|
|
|
|
[self assert:130 equals:[cache _totalCost]];
|
|
|
|
// Hack totalCost then invalidate it to be sure that it is recomputed
|
|
cache._totalCostCache = 650;
|
|
[self assert:650 equals:[cache _totalCost]];
|
|
|
|
cache._totalCostCache = -1;
|
|
[self assert:130 equals:[cache _totalCost]];
|
|
}
|
|
|
|
- (void)testResequencePosition
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50]; // 1 - 1
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:10];
|
|
[cache setObject:@"Object3" forKey:@"key3" cost:70]; // 3 - 2
|
|
[cache removeObjectForKey:@"key2"]
|
|
[cache setObject:@"Object4" forKey:@"key4" cost:70]; // 4 - 3
|
|
|
|
// Before resequence
|
|
[self assert:1 equals:[[cache._items objectForKey:@"key1"] position]];
|
|
[self assert:3 equals:[[cache._items objectForKey:@"key3"] position]];
|
|
[self assert:4 equals:[[cache._items objectForKey:@"key4"] position]];
|
|
|
|
[cache _resequencePosition];
|
|
|
|
// After resequence
|
|
[self assert:1 equals:[[cache._items objectForKey:@"key1"] position]];
|
|
[self assert:2 equals:[[cache._items objectForKey:@"key3"] position]];
|
|
[self assert:3 equals:[[cache._items objectForKey:@"key4"] position]];
|
|
}
|
|
|
|
- (void)testIsTotalCostLimitExceeded
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
|
|
// Not exceed (because of not limit)
|
|
[self assert:NO equals:[cache _isTotalCostLimitExceeded]];
|
|
|
|
// Not exceed (with limit)
|
|
[cache setTotalCostLimit:100];
|
|
[self assert:NO equals:[cache _isTotalCostLimitExceeded]];
|
|
|
|
// Exceed (by hacking the cost of object)
|
|
[[cache._items objectForKey:@"key1"] setCost: 150];
|
|
cache._totalCostCache = -1;
|
|
[self assert:YES equals:[cache _isTotalCostLimitExceeded]];
|
|
}
|
|
|
|
- (void)testIsCountLimitExceeded
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
|
|
// Not exceed (because of not limit)
|
|
[self assert:NO equals:[cache _isCountLimitExceeded]];
|
|
|
|
// Not exceed (with limit)
|
|
[cache setCountLimit:1];
|
|
[self assert:NO equals:[cache _isCountLimitExceeded]];
|
|
|
|
// Exceed (by hacking the items)
|
|
[cache._items setObject:[_CPCacheItem cacheItemWithObject:@"Object2" cost:0 position:3] forKey:@"key2"];
|
|
[self assert:YES equals:[cache _isCountLimitExceeded]];
|
|
}
|
|
|
|
- (void)testCleanCacheWithoutDiscarding
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setTotalCostLimit: 100];
|
|
[cache setCountLimit: 2];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:40];
|
|
|
|
// Set total cost limit
|
|
[cache _cleanCache];
|
|
[self assert:@"Object1" equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
|
|
// Check delegate
|
|
[self assert:0 equals:_countDelegateExecuted];
|
|
}
|
|
|
|
- (void)testCleanCacheWithCostDiscarding
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setTotalCostLimit: 100];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1" cost:50];
|
|
[cache setObject:@"Object2" forKey:@"key2" cost:40];
|
|
|
|
// Hack cost of object
|
|
[[cache._items objectForKey:@"key2"] setCost:80];
|
|
cache._totalCostCache = -1;
|
|
|
|
// Set total cost limit
|
|
[cache _cleanCache];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
}
|
|
|
|
- (void)testCleanCacheWithCountDiscarding
|
|
{
|
|
// Setup cache
|
|
var cache = [[CPCache alloc] init];
|
|
[cache setCountLimit:2];
|
|
[cache setDelegate:self];
|
|
[cache setObject:@"Object1" forKey:@"key1"];
|
|
[cache setObject:@"Object2" forKey:@"key2"];
|
|
|
|
// Hack items
|
|
[cache._items setObject:[_CPCacheItem cacheItemWithObject:@"Object3" cost:0 position:3] forKey:@"key3"];
|
|
|
|
// Set total cost limit
|
|
[cache _cleanCache];
|
|
[self assert:nil equals:[cache objectForKey:@"key1"]];
|
|
[self assert:@"Object2" equals:[cache objectForKey:@"key2"]];
|
|
[self assert:@"Object3" equals:[cache objectForKey:@"key3"]];
|
|
|
|
// Check delegate
|
|
[self assert:1 equals:_countDelegateExecuted];
|
|
[self assert:cache equals:[_caches objectAtIndex:0]];
|
|
[self assert:@"Object1" equals:[_objects objectAtIndex:0]];
|
|
}
|
|
|
|
|
|
@end
|