/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #import #import "LRUCache.h" @interface FBLRUCacheTests : XCTestCase @end @implementation FBLRUCacheTests - (void)assertArray:(NSArray *)array1 equalsTo:(NSArray *)array2 { XCTAssertEqualObjects(array1, array2); } - (void)testRecentlyInsertedObjectReplacesTheOldestOne { LRUCache *cache = [[LRUCache alloc] initWithCapacity:1]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [cache setObject:@"foo3" forKey:@"bar3"]; XCTAssertEqualObjects(@[@"foo3"], cache.allObjects); } - (void)testRecentObjectReplacementAndBump { LRUCache *cache = [[LRUCache alloc] initWithCapacity:2]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [self assertArray:@[@"foo2", @"foo"] equalsTo:cache.allObjects]; XCTAssertNotNil([cache objectForKey:@"bar"]); [self assertArray:@[@"foo", @"foo2"] equalsTo:cache.allObjects]; [cache setObject:@"foo3" forKey:@"bar3"]; [self assertArray:@[@"foo3", @"foo"] equalsTo:cache.allObjects]; [cache setObject:@"foo0" forKey:@"bar"]; [self assertArray:@[@"foo0", @"foo3"] equalsTo:cache.allObjects]; [cache setObject:@"foo4" forKey:@"bar4"]; [self assertArray:@[@"foo4", @"foo0"] equalsTo:cache.allObjects]; } - (void)testBumpFromHead { LRUCache *cache = [[LRUCache alloc] initWithCapacity:3]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [cache setObject:@"foo3" forKey:@"bar3"]; XCTAssertNotNil([cache objectForKey:@"bar3"]); [self assertArray:@[@"foo3", @"foo2", @"foo"] equalsTo:cache.allObjects]; [cache setObject:@"foo4" forKey:@"bar4"]; [cache setObject:@"foo5" forKey:@"bar5"]; [self assertArray:@[@"foo5", @"foo4", @"foo3"] equalsTo:cache.allObjects]; } - (void)testBumpFromMiddle { LRUCache *cache = [[LRUCache alloc] initWithCapacity:3]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [cache setObject:@"foo3" forKey:@"bar3"]; XCTAssertNotNil([cache objectForKey:@"bar2"]); [self assertArray:@[@"foo2", @"foo3", @"foo"] equalsTo:cache.allObjects]; [cache setObject:@"foo4" forKey:@"bar4"]; [cache setObject:@"foo5" forKey:@"bar5"]; [self assertArray:@[@"foo5", @"foo4", @"foo2"] equalsTo:cache.allObjects]; } - (void)testBumpFromTail { LRUCache *cache = [[LRUCache alloc] initWithCapacity:3]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [cache setObject:@"foo3" forKey:@"bar3"]; XCTAssertNotNil([cache objectForKey:@"bar3"]); [self assertArray:@[@"foo3", @"foo2", @"foo"] equalsTo:cache.allObjects]; [cache setObject:@"foo4" forKey:@"bar4"]; [cache setObject:@"foo5" forKey:@"bar5"]; [self assertArray:@[@"foo5", @"foo4", @"foo3"] equalsTo:cache.allObjects]; } - (void)testInsertionLoop { LRUCache *cache = [[LRUCache alloc] initWithCapacity:1]; NSUInteger count = 100; for (NSUInteger i = 0; i <= count; ++i) { [cache setObject:@(i) forKey:@(i)]; XCTAssertNotNil([cache objectForKey:@(i)]); } XCTAssertEqualObjects(@[@(count)], cache.allObjects); } - (void)testRemoveExistingObjectForKey { LRUCache *cache = [[LRUCache alloc] initWithCapacity:3]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [cache setObject:@"foo3" forKey:@"bar3"]; [self assertArray:@[@"foo3", @"foo2", @"foo"] equalsTo:cache.allObjects]; [cache removeObjectForKey:@"bar2"]; XCTAssertNil([cache objectForKey:@"bar2"]); [self assertArray:@[@"foo3", @"foo"] equalsTo:cache.allObjects]; } - (void)testRemoveNonExistingObjectForKey { LRUCache *cache = [[LRUCache alloc] initWithCapacity:2]; [cache setObject:@"foo" forKey:@"bar"]; [cache removeObjectForKey:@"nonExisting"]; XCTAssertNotNil([cache objectForKey:@"bar"]); [self assertArray:@[@"foo"] equalsTo:cache.allObjects]; } - (void)testRemoveAndInsertFlow { LRUCache *cache = [[LRUCache alloc] initWithCapacity:2]; [cache setObject:@"foo" forKey:@"bar"]; [cache setObject:@"foo2" forKey:@"bar2"]; [cache removeObjectForKey:@"bar"]; XCTAssertNil([cache objectForKey:@"bar"]); [cache setObject:@"foo3" forKey:@"bar3"]; [self assertArray:@[@"foo3", @"foo2"] equalsTo:cache.allObjects]; } @end