Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RaceTests.m + handle empty input in PMKRace and PMKRaceFulfilled #1276

Merged
merged 1 commit into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions PromiseKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
63CF6D80203CD19200EC8927 /* ThenableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63CF6D7F203CD19200EC8927 /* ThenableTests.swift */; };
63D9B2EF203385FD0075C00B /* race.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D9B2EE203385FD0075C00B /* race.m */; };
63D9B2F120338D5D0075C00B /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63D9B2F020338D5D0075C00B /* Deprecations.swift */; };
9E66231626FE5A8C00FA25CB /* RaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E66231526FE5A8C00FA25CB /* RaceTests.m */; };
C013F7382048E3B6006B57B1 /* MockNodeEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F7372048E3B6006B57B1 /* MockNodeEnvironment.swift */; };
C013F73A2049076A006B57B1 /* JSPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F7392049076A006B57B1 /* JSPromise.swift */; };
C013F73C20494291006B57B1 /* JSAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F73B20494291006B57B1 /* JSAdapter.swift */; };
Expand Down Expand Up @@ -223,6 +224,7 @@
63CF6D7F203CD19200EC8927 /* ThenableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThenableTests.swift; sourceTree = "<group>"; };
63D9B2EE203385FD0075C00B /* race.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = race.m; path = Sources/race.m; sourceTree = "<group>"; };
63D9B2F020338D5D0075C00B /* Deprecations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Deprecations.swift; path = Sources/Deprecations.swift; sourceTree = "<group>"; };
9E66231526FE5A8C00FA25CB /* RaceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RaceTests.m; sourceTree = "<group>"; };
C013F7372048E3B6006B57B1 /* MockNodeEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MockNodeEnvironment.swift; path = "Tests/JS-A+/MockNodeEnvironment.swift"; sourceTree = "<group>"; };
C013F7392049076A006B57B1 /* JSPromise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = JSPromise.swift; path = "Tests/JS-A+/JSPromise.swift"; sourceTree = "<group>"; };
C013F73B20494291006B57B1 /* JSAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = JSAdapter.swift; path = "Tests/JS-A+/JSAdapter.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -291,6 +293,7 @@
630A8053203CEF6800D25F23 /* JoinTests.m */,
630A8054203CEF6800D25F23 /* HangTests.m */,
630A8055203CEF6800D25F23 /* WhenTests.m */,
9E66231526FE5A8C00FA25CB /* RaceTests.m */,
);
name = CoreObjC;
path = Tests/CoreObjC;
Expand Down Expand Up @@ -684,6 +687,7 @@
630A805B203CF67800D25F23 /* DefaultDispatchQueueTests.swift in Sources */,
635D641D1D59635300BC0AF5 /* PromiseTests.swift in Sources */,
63CF6D7C203CCDAB00EC8927 /* GuaranteeTests.swift in Sources */,
9E66231626FE5A8C00FA25CB /* RaceTests.m in Sources */,
639BF757203DF03100FA577B /* Utilities.swift in Sources */,
635D64261D59635300BC0AF5 /* WhenResolvedTests.swift in Sources */,
635D64231D59635300BC0AF5 /* AfterTests.swift in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions Sources/race.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
// ^^ OSAtomicDecrement32 is deprecated on watchOS

AnyPromise *PMKRace(NSArray *promises) {
if (promises == nil || promises.count == 0)
return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @"PMKRace(nil)"}]];

return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
for (AnyPromise *promise in promises) {
[promise __pipe:resolve];
Expand All @@ -21,6 +24,9 @@
@return The promise that was fulfilled first.
*/
AnyPromise *PMKRaceFulfilled(NSArray *promises) {
if (promises == nil || promises.count == 0)
return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @"PMKRaceFulfilled(nil)"}]];

__block int32_t countdown = (int32_t)[promises count];

return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
Expand Down
48 changes: 0 additions & 48 deletions Tests/CoreObjC/AnyPromiseTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -789,54 +789,6 @@ - (void)test_promiseWithValue {
XCTAssertEqual([AnyPromise promiseWithValue:[AnyPromise promiseWithValue:@1]].value, @1);
}

- (void)test_race {
id ex = [self expectationWithDescription:@""];
id p = PMKAfter(0.1).then(^{ return @2; });
PMKRace(@[PMKAfter(10), PMKAfter(20), p]).then(^(id obj){
XCTAssertEqual(2, [obj integerValue]);
[ex fulfill];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)test_race_fullfilled {
id ex = [self expectationWithDescription:@""];
NSArray* promises = @[
PMKAfter(1).then(^{ return dummyWithCode(1); }),
PMKAfter(2).then(^{ return dummyWithCode(2); }),
PMKAfter(5).then(^{ return @1; }),
PMKAfter(4).then(^{ return @2; }),
PMKAfter(3).then(^{ return dummyWithCode(3); })
];
PMKRaceFulfilled(promises).then(^(id obj){
XCTAssertEqual(2, [obj integerValue]);
[ex fulfill];
}).catch(^{
XCTFail();
[ex fulfill];
});
[self waitForExpectationsWithTimeout:10 handler:nil];
}

- (void)test_race_fullfilled_with_no_winner {
id ex = [self expectationWithDescription:@""];
NSArray* promises = @[
PMKAfter(1).then(^{ return dummyWithCode(1); }),
PMKAfter(2).then(^{ return dummyWithCode(2); }),
PMKAfter(3).then(^{ return dummyWithCode(3); })
];
PMKRaceFulfilled(promises).then(^(id obj){
XCTFail();
[ex fulfill];
}).catch(^(NSError *e){
XCTAssertEqual(e.domain, PMKErrorDomain);
XCTAssertEqual(e.code, PMKNoWinnerError);
XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @"PMKRaceFulfilled(nil)");
[ex fulfill];
});
[self waitForExpectationsWithTimeout:10 handler:nil];
}

- (void)testInBackground {
id ex = [self expectationWithDescription:@""];
PMKAfter(0.1).thenInBackground(^{ [ex fulfill]; });
Expand Down
88 changes: 88 additions & 0 deletions Tests/CoreObjC/RaceTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
@import Foundation;
@import PromiseKit;
@import XCTest;
#define PMKTestErrorDomain @"PMKTestErrorDomain"

static inline NSError *dummyWithCode(NSInteger code) {
return [NSError errorWithDomain:PMKTestErrorDomain code:rand() userInfo:@{NSLocalizedDescriptionKey: @(code).stringValue}];
}

@interface RaceTests : XCTestCase @end @implementation RaceTests

- (void)test_race {
id ex = [self expectationWithDescription:@""];
id p = PMKAfter(0.1).then(^{ return @2; });
PMKRace(@[PMKAfter(10), PMKAfter(20), p]).then(^(id obj){
XCTAssertEqual(2, [obj integerValue]);
[ex fulfill];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)test_race_empty {
id ex = [self expectationWithDescription:@""];
PMKRace(@[]).then(^(NSArray* array){
XCTFail();
[ex fulfill];
}).catch(^(NSError *e){
XCTAssertEqual(e.domain, PMKErrorDomain);
XCTAssertEqual(e.code, PMKInvalidUsageError);
XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @"PMKRace(nil)");
[ex fulfill];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)test_race_fullfilled {
id ex = [self expectationWithDescription:@""];
NSArray* promises = @[
PMKAfter(1).then(^{ return dummyWithCode(1); }),
PMKAfter(2).then(^{ return dummyWithCode(2); }),
PMKAfter(5).then(^{ return @1; }),
PMKAfter(4).then(^{ return @2; }),
PMKAfter(3).then(^{ return dummyWithCode(3); })
];
PMKRaceFulfilled(promises).then(^(id obj){
XCTAssertEqual(2, [obj integerValue]);
[ex fulfill];
}).catch(^{
XCTFail();
[ex fulfill];
});
[self waitForExpectationsWithTimeout:10 handler:nil];
}

- (void)test_race_fulfilled_empty {
id ex = [self expectationWithDescription:@""];
PMKRaceFulfilled(@[]).then(^(NSArray* array){
XCTFail();
[ex fulfill];
}).catch(^(NSError *e){
XCTAssertEqual(e.domain, PMKErrorDomain);
XCTAssertEqual(e.code, PMKInvalidUsageError);
XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @"PMKRaceFulfilled(nil)");
[ex fulfill];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)test_race_fullfilled_with_no_winner {
id ex = [self expectationWithDescription:@""];
NSArray* promises = @[
PMKAfter(1).then(^{ return dummyWithCode(1); }),
PMKAfter(2).then(^{ return dummyWithCode(2); }),
PMKAfter(3).then(^{ return dummyWithCode(3); })
];
PMKRaceFulfilled(promises).then(^(id obj){
XCTFail();
[ex fulfill];
}).catch(^(NSError *e){
XCTAssertEqual(e.domain, PMKErrorDomain);
XCTAssertEqual(e.code, PMKNoWinnerError);
XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @"PMKRaceFulfilled(nil)");
[ex fulfill];
});
[self waitForExpectationsWithTimeout:10 handler:nil];
}

@end