//
//  XTCommandHistoryTests.m
//  TadsTerp
//
//  Created by Rune Berg on 25/06/14.
//  Copyright (c) 2014 Rune Berg. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "XTCommandHistory.h"


@interface XTCommandHistoryTests : XCTestCase

@property XTCommandHistory *commandHistory;

@end


@implementation XTCommandHistoryTests

- (void)setUp
{
    [super setUp];
    self.commandHistory = [XTCommandHistory new];
}

- (void)tearDown
{
    [super tearDown];
}

- (void)testNoEntries
{
    self.commandHistory = [XTCommandHistory new];
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testOneEntry
{
	[self.commandHistory appendCommand:@"cmd1"];
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testTwoEntries
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getNextCommand]);
	}

- (void)testThreeEntries
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
}

- (void)testTrimming_1
{
	[self.commandHistory appendCommand:@" cmd1"];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testTrimming_2
{
	[self.commandHistory appendCommand:@"cmd1 "];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testTrimming_3
{
	[self.commandHistory appendCommand:@" cmd1 "];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testTrimming_4
{
	[self.commandHistory appendCommand:@"cmd  one  "];
	XCTAssertEqualObjects(@"cmd  one", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testTrimming_5
{
	[self.commandHistory appendCommand:@"  cmd   one   "];
	XCTAssertEqualObjects(@"cmd   one", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_1
{
	[self.commandHistory appendCommand:nil];
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_2
{
	[self.commandHistory appendCommand:@""];
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_3
{
	[self.commandHistory appendCommand:@"  "];
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_4
{
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd1"];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_4b
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:nil];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_5
{
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd3"];
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testIgnoredEntries_5b
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"   "];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:nil];
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getNextCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertNil([self.commandHistory getNextCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_1
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd1"];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_1b
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@" cmd1"];
	[self.commandHistory appendCommand:@"cmd1 "];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_2
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd3"];
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_3
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_4
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_5
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_6
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd1"];
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_7
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testRemovalOfSubsequentDuplicates_8
{
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:nil];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"  "];
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)test_hasBeenAccessed
{
	XCTAssertFalse(self.commandHistory.hasBeenAccessed);
	[self.commandHistory appendCommand:@"cmd1"];
	XCTAssertFalse(self.commandHistory.hasBeenAccessed);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertFalse(self.commandHistory.hasBeenAccessed);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertTrue(self.commandHistory.hasBeenAccessed);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
	XCTAssertTrue(self.commandHistory.hasBeenAccessed);
	XCTAssertNil([self.commandHistory getNextCommand]);
	XCTAssertTrue(self.commandHistory.hasBeenAccessed);
}

- (void)test_resetHasBeenAccessed
{
	XCTAssertFalse(self.commandHistory.hasBeenAccessed);
	[self.commandHistory appendCommand:@"cmd1"];
	XCTAssertFalse(self.commandHistory.hasBeenAccessed);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertTrue(self.commandHistory.hasBeenAccessed);
	[self.commandHistory resetHasBeenAccessed];
	XCTAssertFalse(self.commandHistory.hasBeenAccessed);
}

- (void)testPruneExcess_1
{
	self.commandHistory.maxCommandCount = 5;
	self.commandHistory.pruneCommandOverflowBy = 2;
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd4"];
	[self.commandHistory appendCommand:@"cmd5"];
	XCTAssertEqualObjects(@"cmd5", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd4", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd2", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd1", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}
	
- (void)testPruneExcess_2
{
	self.commandHistory.maxCommandCount = 5;
	self.commandHistory.pruneCommandOverflowBy = 2;
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd4"];
	[self.commandHistory appendCommand:@"cmd5"];
	[self.commandHistory appendCommand:@"cmd6"];
	XCTAssertEqualObjects(@"cmd6", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd5", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd4", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testPruneExcess_3
{
	self.commandHistory.maxCommandCount = 5;
	self.commandHistory.pruneCommandOverflowBy = 2;
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd4"];
	[self.commandHistory appendCommand:@"cmd5"];
	[self.commandHistory appendCommand:@"cmd6"];
	[self.commandHistory appendCommand:@"cmd7"];
	XCTAssertEqualObjects(@"cmd7", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd6", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd5", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd4", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd3", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

- (void)testPruneExcess_4
{
	self.commandHistory.maxCommandCount = 5;
	self.commandHistory.pruneCommandOverflowBy = 2;
	[self.commandHistory appendCommand:@"cmd1"];
	[self.commandHistory appendCommand:@"cmd2"];
	[self.commandHistory appendCommand:@"cmd3"];
	[self.commandHistory appendCommand:@"cmd4"];
	[self.commandHistory appendCommand:@"cmd5"];
	[self.commandHistory appendCommand:@"cmd6"];
	[self.commandHistory appendCommand:@"cmd7"];
	[self.commandHistory appendCommand:@"cmd8"];
	[self.commandHistory appendCommand:@"cmd9"];
	XCTAssertEqualObjects(@"cmd9", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd8", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd7", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd6", [self.commandHistory getPreviousCommand]);
	XCTAssertEqualObjects(@"cmd5", [self.commandHistory getPreviousCommand]);
	XCTAssertNil([self.commandHistory getPreviousCommand]);
}

@end
