Skip to content

Commit

Permalink
Merge pull request #1276 from RomanPodymov/feature/race_tests
Browse files Browse the repository at this point in the history
RaceTests.m + handle empty input in PMKRace and PMKRaceFulfilled
  • Loading branch information
mxcl committed Nov 19, 2021
2 parents 00afea5 + ff66460 commit 93c8d41
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 48 deletions.
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

0 comments on commit 93c8d41

Please sign in to comment.