TwitterNetworkLayerTests/TNLURLCodingTest.m (154 lines of code) (raw):

// // TNLURLCodingTest.m // TwitterNetworkLayer // // Created on 11/12/14. // Copyright © 2020 Twitter. All rights reserved. // #import "NSNumber+TNLURLCoding.h" #import "TNLURLCoding.h" @import XCTest; @interface TNLURLCodingTest : XCTestCase @end @implementation TNLURLCodingTest - (void)testURLEncodedString { NSString *original = @"abc ~!@#$%^&*()+=[]{}|\\/,.<>;:'\"☃ 汉字/漢字"; NSString *expected = @"abc%20~%21%40%23%24%25%5E%26%2A%28%29%2B%3D%5B%5D%7B%7D%7C%5C%2F%2C.%3C%3E%3B%3A%27%22%E2%98%83%20%E6%B1%89%E5%AD%97%2F%E6%BC%A2%E5%AD%97"; NSString *encoded = TNLURLEncodeString(original); XCTAssertEqualObjects(encoded, expected, @"TNLURLEncodeString() doesn't match"); NSString *decoded = TNLURLDecodeString(encoded, NO); XCTAssertEqualObjects(decoded, original); expected = [expected stringByReplacingOccurrencesOfString:@"%20" withString:@"+"]; decoded = TNLURLDecodeString(expected, YES); XCTAssertEqualObjects(decoded, original); } - (void)testURLParameterParsing { NSString *query = @"log%5B%5D=%7B%22foo%22%3A%22bar%22%7D"; NSDictionary *dict = TNLURLDecodeDictionary(query, 0); XCTAssertEqualObjects(@"log[]", [[dict allKeys] objectAtIndex:0], @"Unescaped key not found"); XCTAssertEqualObjects(@"{\"foo\":\"bar\"}", [dict objectForKey:@"log[]"], @"Unescaped value not found"); NSString *reverse = TNLURLEncodeDictionary(dict, 0); XCTAssertEqualObjects(query, reverse); query = @"a=one&b=two&c=three&d=four&e=five&g"; NSMutableDictionary *mDict = (id)TNLURLDecodeDictionary(query, TNLURLDecodingOptionOutputMutableDictionary); XCTAssertEqual(6UL, mDict.count); XCTAssertEqualObjects(@"", mDict[@"g"]); mDict[@"g"] = @"six"; reverse = TNLURLEncodeDictionary(mDict, TNLURLEncodingOptionStableOrder); XCTAssertEqualObjects(reverse, [query stringByAppendingString:@"=six"]); reverse = TNLURLEncodeDictionary(mDict, 0); XCTAssertNotEqualObjects(reverse, [query stringByAppendingString:@"=six"]); query = @"a=3=11&b=10=2=1010=A"; dict = TNLURLDecodeDictionary(query, 0); XCTAssertEqualObjects(@"3=11", dict[@"a"]); XCTAssertEqualObjects(@"10=2=1010=A", dict[@"b"]); query = @"a=1+1&b=1%2B1"; dict = TNLURLDecodeDictionary(query, 0); XCTAssertEqualObjects(@"1 1", dict[@"a"]); XCTAssertEqualObjects(@"1+1", dict[@"b"]); dict = TNLURLDecodeDictionary(query, TNLURLDecodingOptionPreservePlusses); XCTAssertEqualObjects(@"1+1", dict[@"a"]); XCTAssertEqualObjects(@"1+1", dict[@"b"]); query = @"=empty&ok=not-empty"; dict = TNLURLDecodeDictionary(query, 0); XCTAssertEqual((NSUInteger)1, (NSUInteger)dict.count); XCTAssertNil(dict[@""]); XCTAssertNotNil(dict[@"ok"]); mDict = [NSMutableDictionary dictionary]; mDict[@""] = @"empty"; mDict[@"ok"] = @"not-empty"; query = TNLURLEncodeDictionary(mDict, 0); XCTAssertEqualObjects(query, @"ok=not-empty"); } - (void)_runNumberCoding:(BOOL)testTiming { NSArray<NSNumber *> *numbers = @[ @((BOOL)YES), @((BOOL)NO), @((BOOL)7), @((uint8_t)0), @((uint8_t)UINT8_MAX), @((int8_t)INT8_MIN), @((int8_t)0), @((int8_t)INT8_MAX), @((uint16_t)0), @((uint16_t)UINT16_MAX), @((int16_t)INT16_MIN), @((int16_t)0), @((int16_t)INT16_MAX), @((uint32_t)0), @((uint32_t)UINT32_MAX), @((int32_t)INT32_MIN), @((int32_t)0), @((int32_t)INT32_MAX), @((uint64_t)0), @((uint64_t)UINT64_MAX), @((int64_t)INT64_MIN), @((int64_t)0), @((int64_t)INT64_MAX), @(FLT_MIN), @(0.f), @(FLT_MAX), @((float)M_PI), @(DBL_MIN), @(0.f), @(DBL_MAX), @(M_PI), ]; NSTimeInterval nsDuration, tnlDuration; const NSUInteger iterations = 20000; #define PRINT_NUMBERS 0 { #if PRINT_NUMBERS BOOL didPrint = NO; #endif const CFAbsoluteTime nsStart = CFAbsoluteTimeGetCurrent(); for (NSUInteger i = 0; i < iterations; i++) { for (NSNumber *number in numbers) { NSString *value = [number stringValue]; #if PRINT_NUMBERS if (!didPrint) { NSLog(@"%@", value); } #endif (void)value; } #if PRINT_NUMBERS didPrint = YES; #endif } const CFAbsoluteTime nsEnd = CFAbsoluteTimeGetCurrent(); nsDuration = nsEnd - nsStart; NSLog(@"-[NSNumber stringValue] = %fs", nsDuration); } { #if PRINT_NUMBERS BOOL didPrint = NO; #endif const CFAbsoluteTime tnlStart = CFAbsoluteTimeGetCurrent(); for (NSUInteger i = 0; i < iterations; i++) { for (NSNumber *number in numbers) { NSString *value = [number tnl_quickStringValue]; #if PRINT_NUMBERS if (!didPrint) { NSLog(@"%@", value); } #endif (void)value; } #if PRINT_NUMBERS didPrint = YES; #endif } const CFAbsoluteTime tnlEnd = CFAbsoluteTimeGetCurrent(); tnlDuration = tnlEnd - tnlStart; NSLog(@"-[NSNumber tnl_quickStringValue] = %fs", tnlDuration); } if (testTiming) { XCTAssertLessThan(tnlDuration, nsDuration, @"-[NSNumber tnl_quickStringValue] ought to be faster than -[NSNumber stringValue]!"); } } - (void)testNumberCoding { [self _runNumberCoding:NO]; } - (void)testNumberCodingSpeed { [self _runNumberCoding:YES]; } @end