// // MPExpressionTests.m // MathPad // // Created by Kim Wittenburg on 19.04.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import #import "MPExpression.h" #import "MPFunction.h" @interface MPExpressionTests : XCTestCase @end @implementation MPExpressionTests - (void)testInitialization { // Test empty expression MPExpression *testExpression = [[MPExpression alloc] init]; XCTAssertEqual(testExpression.numberOfElements, 0); // Test expression with string testExpression = [[MPExpression alloc] initWithElement:@"1234+5678"]; XCTAssertEqual(testExpression.numberOfElements, 1); XCTAssertEqualObjects([testExpression elementAtIndex:0], @"1234+5678"); // Test expression with function testExpression = [[MPExpression alloc] initWithElement:[[MPFunction alloc] init]]; XCTAssertEqual([testExpression numberOfElements], 1); XCTAssertEqualObjects([testExpression elementAtIndex:0], [[MPFunction alloc] init]); testExpression = [[MPExpression alloc] initWithElements:@[@"1234", [[MPFunction alloc] init], @"17", [[MPFunction alloc] init]]]; XCTAssertEqual([testExpression numberOfElements], 4); XCTAssertEqualObjects([testExpression elementAtIndex:2], @"17"); // Test expression with subsequent strings testExpression = [[MPExpression alloc] initWithElements:@[@"1234", @"5678"]]; XCTAssertEqual([testExpression numberOfElements], 1); XCTAssertEqualObjects([testExpression elementAtIndex:0], @"12345678"); // Test expression with only empty string testExpression = [[MPExpression alloc] initWithElement:@""]; XCTAssertEqual([testExpression numberOfElements], 0); } - (void)testSubexpressions { MPExpression *testExpression = [[MPExpression alloc] initWithElements:@[@"1234", [[MPFunction alloc] init], @"17", [[MPFunction alloc] init]]]; /********** subexpressionFromIndex: **********/ // Test with start index at front MPExpression *subexpression = [testExpression subexpressionFromLocation:0]; XCTAssertEqual([subexpression numberOfElements], 4); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"1234"); // Test with start index in first element subexpression = [testExpression subexpressionFromLocation:2]; XCTAssertEqual([subexpression numberOfElements], 4); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"34"); // Test with start index in middle element starting with a literal subexpression = [testExpression subexpressionFromLocation:6]; XCTAssertEqual([subexpression numberOfElements], 2); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"7"); // Test with start index in middle element starting with a function subexpression = [testExpression subexpressionFromLocation:4]; XCTAssertEqual([subexpression numberOfElements], 3); XCTAssertEqualObjects([subexpression elementAtIndex:0], [[MPFunction alloc] init]); // Test with start index in last element subexpression = [testExpression subexpressionFromLocation:7]; XCTAssertEqual([subexpression numberOfElements], 1); XCTAssertEqualObjects([subexpression elementAtIndex:0], [[MPFunction alloc] init]); // Test with start index at end subexpression = [testExpression subexpressionFromLocation:8]; XCTAssertEqual([subexpression numberOfElements], 0); /********** subexpressionToIndex: **********/ // Test with end index at front subexpression = [testExpression subexpressionToLocation:0]; XCTAssertEqual([subexpression numberOfElements], 0); // Test with end index in first Element subexpression = [testExpression subexpressionToLocation:2]; XCTAssertEqual([subexpression numberOfElements], 1); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"12"); // Test with end index in middle Element ending with a literal subexpression = [testExpression subexpressionToLocation:6]; XCTAssertEqual([subexpression numberOfElements], 3); XCTAssertEqualObjects([subexpression elementAtIndex:2], @"1"); // Test with end index in middle Element ending with a function subexpression = [testExpression subexpressionToLocation:5]; XCTAssertEqual([subexpression numberOfElements], 2); XCTAssertEqualObjects([subexpression elementAtIndex:1], [[MPFunction alloc] init]); // Test with end index at end subexpression = [testExpression subexpressionToLocation:8]; XCTAssertEqual([subexpression numberOfElements], 4); XCTAssertEqualObjects([subexpression elementAtIndex:3], [[MPFunction alloc] init]); /********** subexpressionWithRange: **********/ // Test with empty range subexpression = [testExpression subexpressionWithRange:NSMakeRange(4, 0)]; XCTAssertEqual([subexpression numberOfElements], 0); // Test with start and end in first element subexpression = [testExpression subexpressionWithRange:NSMakeRange(1, 2)]; XCTAssertEqual([subexpression numberOfElements], 1); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"23"); // Test with start in first and end in middle after function subexpression = [testExpression subexpressionWithRange:NSMakeRange(2, 3)]; XCTAssertEqual([subexpression numberOfElements], 2); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"34"); XCTAssertEqualObjects([subexpression elementAtIndex:1], [[MPFunction alloc] init]); // Test with start in first and end in middle after literal subexpression = [testExpression subexpressionWithRange:NSMakeRange(2, 4)]; XCTAssertEqual([subexpression numberOfElements], 3); XCTAssertEqualObjects([subexpression elementAtIndex:0], @"34"); XCTAssertEqualObjects([subexpression elementAtIndex:2], @"1"); } - (void)testSubexpressionsIllegalRange { MPExpression *testExpression = [[MPExpression alloc] initWithElements:@[@"1234", [[MPFunction alloc] init], @"17", [[MPFunction alloc] init]]]; // Test with start index beyond end @try { [testExpression subexpressionFromLocation:10]; XCTFail(@"Should have raised an exception."); } @catch (NSException *exception) {} // Test with range extending bounds @try { [testExpression subexpressionWithRange:NSMakeRange(5, 10)]; XCTFail(@"Should have raised an exception."); } @catch (NSException *exception) {} } - (void)testEqualExpressions { MPExpression *expression1 = [[MPExpression alloc] initWithElement:@"123"]; MPExpression *expression2 = [[MPExpression alloc] initWithElement:@"1234"]; MPExpression *expression3 = [[MPExpression alloc] initWithElement:[[MPFunction alloc] init]]; MPExpression *expression4 = [[MPExpression alloc] initWithElements:@[[[MPFunction alloc] init], @"123"]]; MPExpression *expression5 = [[MPExpression alloc] initWithElements:@[[[MPFunction alloc] init], @"123"]]; XCTAssertNotEqualObjects(expression1, expression2); XCTAssertNotEqualObjects(expression1, expression3); XCTAssertNotEqualObjects(expression1, expression4); XCTAssertNotEqualObjects(expression3, expression4); XCTAssertEqualObjects(expression4, expression5); } - (void)testDescription { // Test Simple Expressions MPExpression *testExpression = [[MPExpression alloc] initWithElement:@"1234"]; XCTAssertEqualObjects([testExpression description], @"1234"); testExpression = [[MPExpression alloc] initWithElement:[[MPFunction alloc] init]]; XCTAssertEqualObjects([testExpression description], @"[]"); // Test function after literal without explicit operator testExpression = [[MPExpression alloc] initWithElements:@[@"123", [[MPFunction alloc] init]]]; XCTAssertEqualObjects([testExpression description], @"123*[]"); // Test function after literal with explicit operator testExpression = [[MPExpression alloc] initWithElements:@[@"123+", [[MPFunction alloc] init]]]; XCTAssertEqualObjects([testExpression description], @"123+[]"); // Test literal after function without explicit operator testExpression = [[MPExpression alloc] initWithElements:@[[[MPFunction alloc] init], @"123"]]; XCTAssertEqualObjects([testExpression description], @"[]*123"); // Test literal after function with explicit operator testExpression = [[MPExpression alloc] initWithElements:@[[[MPFunction alloc] init], @"-123"]]; XCTAssertEqualObjects([testExpression description], @"[]-123"); // Test function after function without explicit operator testExpression = [[MPExpression alloc] initWithElements:@[[[MPFunction alloc] init], [[MPFunction alloc] init]]]; XCTAssertEqualObjects([testExpression description], @"[]*[]"); // Test function after function with explicit operator testExpression = [[MPExpression alloc] initWithElements:@[[[MPFunction alloc] init], @"-", [[MPFunction alloc] init]]]; XCTAssertEqualObjects([testExpression description], @"[]-[]"); // Test whitespaces in literal testExpression = [[MPExpression alloc] initWithElements:@[@" 123 + ", [[MPFunction alloc] init]]]; XCTAssertEqualObjects([testExpression description], @"123 +[]"); } - (void)testCopying { MPExpression *baseExpression = [[MPExpression alloc] initWithElement:[[MPFunction alloc] init]]; MPExpression *copy = [baseExpression copy]; XCTAssertEqual(baseExpression.numberOfElements, copy.numberOfElements); XCTAssertNotEqual(copy, baseExpression); XCTAssertNotEqual([baseExpression elementAtIndex:0], [copy elementAtIndex:0]); XCTAssertEqualObjects(baseExpression, copy); } - (void)testMutating { MPExpression *testExpression = [[MPExpression alloc] initWithElements:@[@"1234", [[MPFunction alloc] init], @"5678", [[MPFunction alloc] init]]]; [testExpression appendElement:@"90"]; XCTAssertEqual([testExpression numberOfElements], 5); // 1234 [] 5678 [] 90 [testExpression deleteElementsInRange:NSMakeRange(2, 4)]; XCTAssertEqual([testExpression numberOfElements], 3); // 12678 [] 90 [testExpression deleteElementsInRange:NSMakeRange(0, 2)]; XCTAssertEqual([testExpression numberOfElements], 3); XCTAssertEqualObjects([testExpression elementAtIndex:0], @"678"); [testExpression insertElement:[[MPFunction alloc] init] atLocation:2]; XCTAssertEqual([testExpression numberOfElements], 5); // 67 [] 8 [] 90 [testExpression replaceSymbolsInRange:NSMakeRange(2, 5) withElements:@[[[MPFunction alloc] init]]]; XCTAssertEqual([testExpression numberOfElements], 2); XCTAssertEqualObjects([testExpression elementAtIndex:0], @"67"); // 67 [] } - (void)testInvalidMutatingRange { @try { MPExpression *testExpression = [[MPExpression alloc] initWithElements:@[@"1234", [[MPFunction alloc] init], @"5678", [[MPFunction alloc] init]]]; [testExpression deleteElementsInRange:NSMakeRange(5, 17)]; XCTFail(@"Should have raised an exception"); } @catch (NSException *exception) {} } // TODO: Test evaluating expressions @end