ComponentKitTests/CKVectorHelperTests.mm (233 lines of code) (raw):

/* * Copyright (c) 2014-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. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import <stdlib.h> #import <unordered_map> #import <vector> #import <XCTest/XCTest.h> #import <ComponentKit/CKCollection.h> #import <ComponentKit/CKFunctionalHelpers.h> @interface CKVectorChainingTests : XCTestCase @end @implementation CKVectorChainingTests - (void)test_emptyVectors { std::vector<int> a; std::vector<int> b; std::vector<int> emptyVector; XCTAssertTrue(CK::chain(a,b) == emptyVector); } - (void)test_firstVectorEmpty { std::vector<int> a; std::vector<int> b = {1,2,3}; XCTAssertTrue(CK::chain(a,b) == b); } - (void)test_secondVectorEmpty { std::vector<int> a = {1,2,3}; std::vector<int> b; XCTAssertTrue(CK::chain(a,b) == a); } - (void)test_chainingTwoVectors { std::vector<int> a = {1,2,3}; std::vector<int> b = {4,5,6}; std::vector<int> c = {1,2,3,4,5,6}; XCTAssertTrue(CK::chain(a,b) == c); } - (void)test_chainingVectorWithItself { std::vector<int> a = {1,2,3}; std::vector<int> aa = {1,2,3,1,2,3}; XCTAssertTrue(CK::chain(a,a) == aa); } - (void)test_chainingVectorsOfDifferentLengths { std::vector<int> a = {1,2,3}; std::vector<int> b = {4,5,6,7,8}; std::vector<int> c = {1,2,3,4,5,6,7,8}; XCTAssertTrue(CK::chain(a,b) == c); } - (void)test_chainingCallsToChain { std::vector<int> a = {1,2,3}; std::vector<int> b = {4,5,6}; std::vector<int> c = {7,8,9}; std::vector<int> d = {1,2,3,4,5,6,7,8,9}; XCTAssertTrue(CK::chain(CK::chain(a, b), c) == d); } @end @interface CKVectorMapTests : XCTestCase @end @implementation CKVectorMapTests - (void)test_mapEmptyVector { std::vector<NSString *> a = {}; std::vector<int> b = CK::map(a, ^int(NSString *str) { return str.intValue; }); std::vector<int> c = {}; XCTAssertTrue(b == c); } - (void)test_mapVectorWithObjects { std::vector<NSString *> a = {@"1", @"2", @"3"}; std::vector<int> b = CK::map(a, ^int(NSString *str) { return str.intValue; }); std::vector<int> c = {1, 2, 3}; XCTAssertTrue(b == c); } - (void)test_mapWithIndexVectorWithObjects { NSArray<NSString *> *a = @[@"1", @"2", @"3"]; __block NSUInteger idx = 0; std::vector<int> b = CK::mapWithIndex(a, ^int(NSString *str, NSUInteger index) { XCTAssertTrue(idx == index); idx++; return str.intValue; }); std::vector<int> c = {1, 2, 3}; XCTAssertTrue(b == c); } - (void)test_mapWithIndexVectorWithStructs { struct InputStruct { NSString *string; NSInteger integer; }; struct OutputStruct { NSUInteger index; NSInteger integer; NSString *string; }; std::vector<InputStruct> ts = { {.string = @"a", .integer = 10}, {.string = @"b", .integer = 20}, {.string = @"c", .integer = -30} }; std::vector<OutputStruct> rs = { {.string = @"a", .integer = 10, .index = 0}, {.string = @"b", .integer = 20, .index = 1}, {.string = @"c", .integer = -30, .index = 2} }; std::vector<OutputStruct> result = CK::mapWithIndex(ts, ^OutputStruct(InputStruct input, NSUInteger index) { return { .index = index, .integer = input.integer, .string = input.string, }; }); auto outputStructsEqual = [](OutputStruct &lhs, OutputStruct& rhs) { return [lhs.string isEqualToString:rhs.string] && lhs.integer == rhs.integer && lhs.index == rhs.index; }; XCTAssertTrue(result.size() == rs.size()); for (int i = 0; i < rs.size(); i++) { XCTAssertTrue(outputStructsEqual(rs.at(i), result.at(i))); } } - (void)test_mapVectorWithStructs { struct TestStruct { int i; }; std::vector<TestStruct> a = {{.i = 1}, {.i = 2}, {.i = 3}}; std::vector<int> b = CK::map(a, ^int(TestStruct s) { return s.i; }); std::vector<int> c = {1, 2, 3}; XCTAssertTrue(b == c); } @end @interface CKVectorFilterTests : XCTestCase @end @implementation CKVectorFilterTests - (void)test_filterEmptyVector { std::vector<int> a = {}; std::vector<int> b = CK::filter(a, ^BOOL(int var) { return var % 2 == 0; }); std::vector<int> c = {}; XCTAssertTrue(b == c); } - (void)test_filterVectorWithObjects { std::vector<NSString *> a = {@"1", @"2", @"3", @"4"}; std::vector<NSString *> b = CK::filter(a, ^BOOL(NSString *str) { return str.intValue % 2 == 0; }); std::vector<NSString *> c = {@"2", @"4"}; XCTAssertTrue(b == c); } - (void)test_filterVectorWithPrimitives { std::vector<int> a = {1, 2, 3, 4}; std::vector<int> b = CK::filter(a, ^BOOL(int var) { return var % 2 == 0; }); std::vector<int> c = {2, 4}; XCTAssertTrue(b == c); } - (void)test_filterVectorWithStructs { struct TestStruct { int i; bool operator==(const TestStruct& rhs) const { return i == rhs.i; } }; std::vector<TestStruct> a = {{.i = 1}, {.i = 2}, {.i = 3}, {.i = 4}}; std::vector<TestStruct> b = CK::filter(a, ^BOOL(TestStruct s) { return s.i % 2 == 0; }); std::vector<TestStruct> c = {{.i = 2}, {.i = 4}}; XCTAssertTrue(b == c); } @end @interface CKVectorInterspersingTests : XCTestCase @end @implementation CKVectorInterspersingTests - (void)test_emptyVector { std::vector<int> a = {}; std::vector<int> expected = {}; XCTAssertTrue(CK::intersperse(a, ^int{ return 0; }) == expected); } - (void)test_intersperseSingleItem { std::vector<int> a = {1}; std::vector<int> expected = {1}; XCTAssertTrue(CK::intersperse(a, ^int{ return 4; }) == expected); } - (void)test_intersperseMultipleItems { std::vector<int> a = {1,2,3}; std::vector<int> expected = {1,4,2,4,3}; XCTAssertTrue(CK::intersperse(a, ^int{ return 4; }) == expected); } - (void)test_intersperseTwice { std::vector<int> a = {1,2,3}; std::vector<int> b = CK::intersperse(a, ^int{ return 4; }); std::vector<int> expected = {1,5,4,5,2,5,4,5,3}; XCTAssertTrue(CK::intersperse(b, ^int{ return 5; }) == expected); } @end @interface CKCollectionTests : XCTestCase @end @implementation CKCollectionTests - (void)test_WhenMapDoesNotHaveKey_ValueForKeyReturnsNone { auto const map = std::unordered_map<int, int>{ {1, 2} }; XCTAssert(CK::Collection::valueForKey(map, 2) == CK::none); } - (void)test_WhenMapHasKey_ValueForKeyReturnsValue { auto const map = std::unordered_map<int, int>{ {1, 2} }; XCTAssert(CK::Collection::valueForKey(map, 1) == 2); } @end