From 0a4ad1f21f032105f98e767d7d19f6bbfa003b18 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 11 May 2025 06:39:04 +0200 Subject: [PATCH 1/6] Run tests in CI --- .github/workflows/BuildPR.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/BuildPR.yml b/.github/workflows/BuildPR.yml index 3be5d9f2..12fdcd3f 100644 --- a/.github/workflows/BuildPR.yml +++ b/.github/workflows/BuildPR.yml @@ -47,7 +47,7 @@ jobs: - name: Unlink openssl 3 run: | brew unlink openssl@3 -# - name: Test project -# run: xcodebuild -workspace ObjectiveGitFramework.xcworkspace -scheme "ObjectiveGit Mac" test ARCHS="${{ matrix.abi }}" + - name: Test project + run: xcodebuild -workspace ObjectiveGitFramework.xcworkspace -scheme "ObjectiveGit Mac" test ARCHS="${{ matrix.abi }}" - name: Archive project run: xcodebuild -workspace ObjectiveGitFramework.xcworkspace -scheme "ObjectiveGit Mac" archive ARCHS="${{ matrix.abi }}" From cb09bcf58d48af9bcfa9e8c259b2a86832899c5d Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Mon, 28 Sep 2026 07:30:14 +0200 Subject: [PATCH 2/6] Stop signing Debug builds with SHA-1 The vendored Carthage/Checkouts/xcconfigs Base/Configurations/Debug.xcconfig hardcodes OTHER_CODE_SIGN_FLAGS = --digest-algorithm=sha1 --timestamp=none for every Debug build. Current codesign refuses SHA-1 outright: error: signing with only SHA1 not allowed. Please remove `sha1` from the `--digest-algorithm` code signing flag. which was breaking ObjectiveGit-MacTests' CodeSign build phase (and would break the ObjectiveGit-Mac framework and ObjectiveGit-iOS target the same way, since they share the same project-level Debug config). Since Base/Configurations/Debug.xcconfig lives in a separate vendored git submodule (jspahrsummers/xcconfigs) fetched fresh by script/bootstrap on every CI run, patching it directly wouldn't survive a bootstrap. Instead, override OTHER_CODE_SIGN_FLAGS directly in the project's own Debug build configuration, which takes precedence over the same key supplied by baseConfigurationReference. Keeps --timestamp=none (skips the network-dependent Developer ID timestamp server, still fine for local/CI ad-hoc signing) and just drops the now-rejected --digest-algorithm=sha1. --- ObjectiveGitFramework.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ObjectiveGitFramework.xcodeproj/project.pbxproj b/ObjectiveGitFramework.xcodeproj/project.pbxproj index 00ea3c9a..eb933bc3 100644 --- a/ObjectiveGitFramework.xcodeproj/project.pbxproj +++ b/ObjectiveGitFramework.xcodeproj/project.pbxproj @@ -1763,6 +1763,12 @@ "$(inherited)", "-DGIT_SSH", ); + // Override the vendored Carthage/Checkouts/xcconfigs Debug.xcconfig, + // which hardcodes "--digest-algorithm=sha1". Current codesign + // rejects SHA-1 outright ("signing with only SHA1 not allowed"), + // so drop it here and keep only the network-independent timestamp + // opt-out. + OTHER_CODE_SIGN_FLAGS = "--timestamp=none"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; WARNING_CFLAGS = ( From 5080b8fbcc629a7bb6bb4de7c5789457e3212598 Mon Sep 17 00:00:00 2001 From: Gonen <830775+goneng@users.noreply.github.com> Date: Mon, 21 Sep 2026 18:13:59 +0300 Subject: [PATCH 3/6] Fix the test target having no architecture to build for The vendored xcconfig caps Mac targets at x86_64, which leaves the test target with nothing valid to build on Apple Silicon. - Override VALID_ARCHS with "x86_64 arm64" on all four test configurations, matching what the framework target already does. - Without it the target produces no binary and the build stops at "Build input file cannot be found" before compiling a single source file, so none of the errors behind it were ever visible. --- ObjectiveGitFramework.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ObjectiveGitFramework.xcodeproj/project.pbxproj b/ObjectiveGitFramework.xcodeproj/project.pbxproj index eb933bc3..61072f74 100644 --- a/ObjectiveGitFramework.xcodeproj/project.pbxproj +++ b/ObjectiveGitFramework.xcodeproj/project.pbxproj @@ -1889,6 +1889,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.libgit2.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; + VALID_ARCHS = "x86_64 arm64"; }; name = Debug; }; @@ -1910,6 +1911,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.libgit2.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; + VALID_ARCHS = "x86_64 arm64"; }; name = Release; }; @@ -1996,6 +1998,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.libgit2.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; + VALID_ARCHS = "x86_64 arm64"; }; name = Test; }; @@ -2214,6 +2217,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.libgit2.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; + VALID_ARCHS = "x86_64 arm64"; }; name = Profile; }; From 54710b50e8f920bc1a7f288a5299dcbb69557b65 Mon Sep 17 00:00:00 2001 From: Gonen <830775+goneng@users.noreply.github.com> Date: Mon, 21 Sep 2026 18:14:14 +0300 Subject: [PATCH 4/6] Fix the buffer specs reading a git_buf field libgit2 removed git_buf dropped its asize member when libgit2 1.x moved the allocated size into reserved, so the NSData specs stopped compiling. - Read buffer.reserved instead. git_buf_grow still writes the allocation size there, so all three assertions keep the meaning they had against 0.28. - Leave the deprecated git_buf and git_strarray calls around them alone; they still resolve through deprecated.h, which carries no deprecation attribute, and removing them belongs with the rest of the shim cleanup. --- ObjectiveGitTests/NSDataGitSpec.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ObjectiveGitTests/NSDataGitSpec.m b/ObjectiveGitTests/NSDataGitSpec.m index bc54ea77..82c4886d 100644 --- a/ObjectiveGitTests/NSDataGitSpec.m +++ b/ObjectiveGitTests/NSDataGitSpec.m @@ -27,7 +27,7 @@ expect([NSValue valueWithPointer:buffer.ptr]).notTo(equal([NSValue valueWithPointer:NULL])); expect([NSValue valueWithPointer:buffer.ptr]).notTo(equal([NSValue valueWithPointer:testData])); expect(@(buffer.size)).to(equal(@(testDataSize))); - expect(@(buffer.asize)).to(beGreaterThanOrEqualTo(@(testDataSize))); + expect(@(buffer.reserved)).to(beGreaterThanOrEqualTo(@(testDataSize))); }); afterEach(^{ @@ -46,7 +46,7 @@ [NSData git_dataWithBuffer:&buffer]; expect(@(buffer.size)).to(equal(@0)); - expect(@(buffer.asize)).to(equal(@0)); + expect(@(buffer.reserved)).to(equal(@0)); expect([NSValue valueWithPointer:buffer.ptr]).to(equal([NSValue valueWithPointer:NULL])); }); }); @@ -63,7 +63,7 @@ git_buf buffer = data.git_buf; expect([NSValue valueWithPointer:buffer.ptr]).to(equal([NSValue valueWithPointer:data.bytes])); expect(@(buffer.size)).to(equal(@(data.length))); - expect(@(buffer.asize)).to(equal(@0)); + expect(@(buffer.reserved)).to(equal(@0)); }); }); From eba13801d3e6c0c874c7627b8646fcd022fca9fc Mon Sep 17 00:00:00 2001 From: Gonen <830775+goneng@users.noreply.github.com> Date: Mon, 21 Sep 2026 18:14:36 +0300 Subject: [PATCH 5/6] Fix the specs addressing the spec class as an instance Quick 7 turned the spec entry point into a class method, so self in a spec body is now the spec class rather than the example being run, and the fixture helpers are instance methods on QuickSpec. - Send the fixture helpers to QuickSpec.current, the instance XCTest is running, so each example still gets its own temp directory. - Give SwiftSpec the class-method signature so it overrides Quick's spec() again. Swift compiles first in a mixed target, so this one error hid every Objective-C error behind it. - Fourteen of these were hard errors. The rest compiled only because clang allows any known selector on a bare Class, and would have raised unrecognized selector at run time. --- ObjectiveGitTests/GTBlameSpec.m | 10 ++--- ObjectiveGitTests/GTBlobSpec.m | 6 +-- ObjectiveGitTests/GTBranchSpec.m | 6 +-- ObjectiveGitTests/GTCommitSpec.m | 4 +- ObjectiveGitTests/GTConfigurationSpec.m | 2 +- ObjectiveGitTests/GTDiffDeltaSpec.m | 2 +- ObjectiveGitTests/GTDiffSpec.m | 6 +-- ObjectiveGitTests/GTEnumeratorSpec.m | 4 +- ObjectiveGitTests/GTFilterListSpec.m | 6 +-- ObjectiveGitTests/GTFilterSpec.m | 4 +- ObjectiveGitTests/GTIndexSpec.m | 20 +++++----- ObjectiveGitTests/GTNoteSpec.m | 4 +- ObjectiveGitTests/GTOIDSpec.m | 2 +- ObjectiveGitTests/GTObjectDatabaseSpec.m | 4 +- ObjectiveGitTests/GTObjectSpec.m | 2 +- ObjectiveGitTests/GTReferenceSpec.m | 8 ++-- ObjectiveGitTests/GTReflogSpec.m | 4 +- ObjectiveGitTests/GTRemotePushSpec.m | 2 +- ObjectiveGitTests/GTRemoteSpec.m | 4 +- ObjectiveGitTests/GTRepository+PullSpec.m | 2 +- ObjectiveGitTests/GTRepository+StatusSpec.m | 4 +- .../GTRepositoryAttributesSpec.m | 2 +- .../GTRepositoryCommittingSpec.m | 4 +- ObjectiveGitTests/GTRepositoryResetSpec.m | 6 +-- ObjectiveGitTests/GTRepositorySpec.m | 38 +++++++++---------- ObjectiveGitTests/GTRepositoryStashingSpec.m | 4 +- ObjectiveGitTests/GTSignatureSpec.m | 2 +- ObjectiveGitTests/GTSubmoduleSpec.m | 4 +- ObjectiveGitTests/GTTagSpec.m | 4 +- ObjectiveGitTests/GTTimeAdditionsSpec.m | 2 +- ObjectiveGitTests/GTTreeBuilderSpec.m | 4 +- ObjectiveGitTests/GTTreeSpec.m | 4 +- ObjectiveGitTests/NSArray+StringArraySpec.m | 2 +- ObjectiveGitTests/NSDataGitSpec.m | 2 +- ObjectiveGitTests/NSErrorGitSpec.m | 2 +- ObjectiveGitTests/SwiftSpec.swift | 2 +- 36 files changed, 94 insertions(+), 94 deletions(-) diff --git a/ObjectiveGitTests/GTBlameSpec.m b/ObjectiveGitTests/GTBlameSpec.m index 2cbeec1a..f1948c26 100644 --- a/ObjectiveGitTests/GTBlameSpec.m +++ b/ObjectiveGitTests/GTBlameSpec.m @@ -17,7 +17,7 @@ __block GTBlame *blame = nil; beforeEach(^{ - blame = [self.testAppFixtureRepository blameWithFile:@"README1.txt" options:nil error:nil]; + blame = [QuickSpec.current.testAppFixtureRepository blameWithFile:@"README1.txt" options:nil error:nil]; expect(blame).notTo(beNil()); }); @@ -59,7 +59,7 @@ describe(@"Creating a blame with options", ^{ it(@"should follow the instructions provided by the GTBlameOptionsOldestCommitOID key", ^{ - GTBlame *optionsBlame = [self.testAppFixtureRepository blameWithFile:@"README1.txt" options:@{ GTBlameOptionsOldestCommitOID: [GTOID oidWithSHA:@"1d69f3c0aeaf0d62e25591987b93b8ffc53abd77"] } error:nil]; + GTBlame *optionsBlame = [QuickSpec.current.testAppFixtureRepository blameWithFile:@"README1.txt" options:@{ GTBlameOptionsOldestCommitOID: [GTOID oidWithSHA:@"1d69f3c0aeaf0d62e25591987b93b8ffc53abd77"] } error:nil]; expect(optionsBlame).notTo(beNil()); expect(optionsBlame).notTo(equal(blame)); @@ -67,7 +67,7 @@ it(@"should follow the instructions provided by the GTBlameOptionsNewestCommitOID key", ^{ GTOID *newOID = [GTOID oidWithSHA:@"6317779b4731d9c837dcc6972b964bdf4211eeef"]; - GTBlame *optionsBlame = [self.testAppFixtureRepository blameWithFile:@"README1.txt" options:@{ GTBlameOptionsNewestCommitOID: newOID } error:nil]; + GTBlame *optionsBlame = [QuickSpec.current.testAppFixtureRepository blameWithFile:@"README1.txt" options:@{ GTBlameOptionsNewestCommitOID: newOID } error:nil]; GTBlameHunk *hunk = [optionsBlame hunkAtIndex:0]; expect(@(hunk.lines.location)).to(equal(@1)); @@ -75,7 +75,7 @@ }); it(@"should follow the instructions provided by GTBlameOptionsFirstLine and GTBlameOptionsLastLine keys", ^{ - GTBlame *optionsBlame = [self.testAppFixtureRepository blameWithFile:@"README1.txt" options:@{ GTBlameOptionsFirstLine: @22, GTBlameOptionsLastLine: @24 } error:nil]; + GTBlame *optionsBlame = [QuickSpec.current.testAppFixtureRepository blameWithFile:@"README1.txt" options:@{ GTBlameOptionsFirstLine: @22, GTBlameOptionsLastLine: @24 } error:nil]; GTBlameHunk *hunk = [optionsBlame hunkAtIndex:0]; expect(optionsBlame).notTo(beNil()); @@ -85,7 +85,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTBlobSpec.m b/ObjectiveGitTests/GTBlobSpec.m index 97e73533..dbb1f416 100644 --- a/ObjectiveGitTests/GTBlobSpec.m +++ b/ObjectiveGitTests/GTBlobSpec.m @@ -20,7 +20,7 @@ describe(@"blob properties can be accessed", ^{ beforeEach(^{ - repository = self.bareFixtureRepository; + repository = QuickSpec.current.bareFixtureRepository; blobSHA = @"fa49b077972391ad58037050f2a75f74e3671e92"; blob = [repository lookUpObjectBySHA:blobSHA objectType:GTObjectTypeBlob error:NULL]; expect(blob).notTo(beNil()); @@ -45,7 +45,7 @@ describe(@"blobs can be created", ^{ beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; }); describe(@"+blobWithString:inRepository:error", ^{ @@ -92,7 +92,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTBranchSpec.m b/ObjectiveGitTests/GTBranchSpec.m index 2b997e22..d1164708 100644 --- a/ObjectiveGitTests/GTBranchSpec.m +++ b/ObjectiveGitTests/GTBranchSpec.m @@ -19,7 +19,7 @@ __block GTBranch *trackingBranch; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); NSError *error = nil; @@ -240,7 +240,7 @@ }); it(@"should set a remote tracking branch without branches amount change", ^{ - GTRepository *repository = self.testAppForkFixtureRepository; + GTRepository *repository = QuickSpec.current.testAppForkFixtureRepository; expect(repository).notTo(beNil()); NSError *error = nil; @@ -307,7 +307,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTCommitSpec.m b/ObjectiveGitTests/GTCommitSpec.m index 38ebe87f..7343d2f6 100644 --- a/ObjectiveGitTests/GTCommitSpec.m +++ b/ObjectiveGitTests/GTCommitSpec.m @@ -17,7 +17,7 @@ __block GTRepository *repository; beforeEach(^{ - repository = self.bareFixtureRepository; + repository = QuickSpec.current.bareFixtureRepository; }); it(@"can read commit data", ^{ @@ -81,7 +81,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTConfigurationSpec.m b/ObjectiveGitTests/GTConfigurationSpec.m index 25f3c124..85a3cb8b 100644 --- a/ObjectiveGitTests/GTConfigurationSpec.m +++ b/ObjectiveGitTests/GTConfigurationSpec.m @@ -52,7 +52,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTDiffDeltaSpec.m b/ObjectiveGitTests/GTDiffDeltaSpec.m index 81c1ae0e..ad0b3fdb 100644 --- a/ObjectiveGitTests/GTDiffDeltaSpec.m +++ b/ObjectiveGitTests/GTDiffDeltaSpec.m @@ -18,7 +18,7 @@ __block GTDiffDelta *delta; beforeEach(^{ - repository = [self testAppFixtureRepository]; + repository = [QuickSpec.current testAppFixtureRepository]; }); describe(@"blob-to-blob diffing", ^{ diff --git a/ObjectiveGitTests/GTDiffSpec.m b/ObjectiveGitTests/GTDiffSpec.m index 0ad3eea8..8bda7757 100644 --- a/ObjectiveGitTests/GTDiffSpec.m +++ b/ObjectiveGitTests/GTDiffSpec.m @@ -21,7 +21,7 @@ __block GTCommit *secondCommit = nil; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); firstCommit = (GTCommit *)[repository lookUpObjectBySHA:@"8e0e65988d3007867a9f59ca8639ba975ef97e69" objectType:GTObjectTypeCommit error:NULL]; @@ -72,7 +72,7 @@ __block void (^setupDiffFromCommitSHAsAndOptions)(NSString *, NSString *, NSDictionary *) = nil; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); setupDiffFromCommitSHAsAndOptions = [^(NSString *firstCommitSHA, NSString *secondCommitSHA, NSDictionary *options) { @@ -294,7 +294,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTEnumeratorSpec.m b/ObjectiveGitTests/GTEnumeratorSpec.m index 70f4e478..0bcd7d42 100644 --- a/ObjectiveGitTests/GTEnumeratorSpec.m +++ b/ObjectiveGitTests/GTEnumeratorSpec.m @@ -18,7 +18,7 @@ __block GTEnumerator *enumerator; beforeEach(^{ - repo = self.bareFixtureRepository; + repo = QuickSpec.current.bareFixtureRepository; expect(repo).notTo(beNil()); enumerator = [[GTEnumerator alloc] initWithRepository:repo error:NULL]; @@ -152,7 +152,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTFilterListSpec.m b/ObjectiveGitTests/GTFilterListSpec.m index 97313a56..a70af160 100644 --- a/ObjectiveGitTests/GTFilterListSpec.m +++ b/ObjectiveGitTests/GTFilterListSpec.m @@ -23,7 +23,7 @@ NSString *textFilterContent = @"\nohai text-filter!"; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; NSString *attributes = @"READ* rf=true\n*.txt tf=true\n"; BOOL success = [attributes writeToURL:[repository.fileURL URLByAppendingPathComponent:@".gitattributes"] atomically:YES encoding:NSUTF8StringEncoding error:NULL]; @@ -144,7 +144,7 @@ it(@"should apply to a file", ^{ NSString *inputFilename = @"README"; - GTRepository *inputRepo = self.conflictedFixtureRepository; + GTRepository *inputRepo = QuickSpec.current.conflictedFixtureRepository; NSString *content = [NSString stringWithContentsOfURL:[inputRepo.fileURL URLByAppendingPathComponent:inputFilename] encoding:NSUTF8StringEncoding error:NULL]; expect(content).notTo(contain(readFilterContent)); @@ -183,7 +183,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTFilterSpec.m b/ObjectiveGitTests/GTFilterSpec.m index 7ab7a559..b396c10d 100644 --- a/ObjectiveGitTests/GTFilterSpec.m +++ b/ObjectiveGitTests/GTFilterSpec.m @@ -28,7 +28,7 @@ __block void (^setUpFilterWithApplyBlock)(GTFilterApplyBlock block); beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); NSString *attributes = @"*.txt special\n"; @@ -184,7 +184,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTIndexSpec.m b/ObjectiveGitTests/GTIndexSpec.m index 4e894153..68a2319e 100644 --- a/ObjectiveGitTests/GTIndexSpec.m +++ b/ObjectiveGitTests/GTIndexSpec.m @@ -18,7 +18,7 @@ __block GTIndex *index; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; index = [repository indexWithError:NULL]; expect(index).notTo(beNil()); @@ -51,7 +51,7 @@ }); it(@"should write to a specific repository and return a tree", ^{ - GTRepository *repository = self.bareFixtureRepository; + GTRepository *repository = QuickSpec.current.bareFixtureRepository; NSArray *branches = [repository branches:NULL]; GTCommit *masterCommit = [branches[0] targetCommitWithError:NULL]; GTCommit *packedCommit = [branches[1] targetCommitWithError:NULL]; @@ -115,13 +115,13 @@ }); it(@"should correctly report conflicts", ^{ - index = [self.conflictedFixtureRepository indexWithError:NULL]; + index = [QuickSpec.current.conflictedFixtureRepository indexWithError:NULL]; expect(index).notTo(beNil()); expect(@(index.hasConflicts)).to(beTruthy()); }); it(@"should enumerate conflicts successfully", ^{ - index = [self.conflictedFixtureRepository indexWithError:NULL]; + index = [QuickSpec.current.conflictedFixtureRepository indexWithError:NULL]; expect(index).notTo(beNil()); NSError *err = NULL; @@ -141,8 +141,8 @@ describe(@"updating pathspecs", ^{ NSString *fileName = @"REAME_"; beforeEach(^{ - index = [self.testAppFixtureRepository indexWithError:NULL]; - NSString *filePath = [self.testAppFixtureRepository.fileURL.path stringByAppendingPathComponent:fileName]; + index = [QuickSpec.current.testAppFixtureRepository indexWithError:NULL]; + NSString *filePath = [QuickSpec.current.testAppFixtureRepository.fileURL.path stringByAppendingPathComponent:fileName]; [@"The wild west..." writeToFile:filePath atomically:NO encoding:NSUTF8StringEncoding error:NULL]; expect(index).notTo(beNil()); @@ -175,7 +175,7 @@ it(@"should stop be able to stop early", ^{ NSString *otherFileName = @"TestAppDelegate.h"; - [@"WELP" writeToFile:[self.testAppFixtureRepository.fileURL.path stringByAppendingPathComponent:otherFileName] atomically:NO encoding:NSUTF8StringEncoding error:NULL]; + [@"WELP" writeToFile:[QuickSpec.current.testAppFixtureRepository.fileURL.path stringByAppendingPathComponent:otherFileName] atomically:NO encoding:NSUTF8StringEncoding error:NULL]; BOOL success = [index updatePathspecs:NULL error:NULL passingTest:^(NSString *matchedPathspec, NSString *path, BOOL *stop) { if ([path.lastPathComponent isEqualToString:fileName]) { *stop = YES; @@ -212,7 +212,7 @@ beforeEach(^{ expect(filename).to(equal([filename precomposedStringWithCanonicalMapping])); - repo = self.testUnicodeFixtureRepository; + repo = QuickSpec.current.testUnicodeFixtureRepository; configuration = [repo configurationWithError:NULL]; [configuration setBool:false forKey:@"core.precomposeunicode"]; @@ -310,7 +310,7 @@ beforeEach(^{ error = nil; - repo = self.testUnicodeFixtureRepository; + repo = QuickSpec.current.testUnicodeFixtureRepository; // Not sure why but it doesn't work with an in memory index // index = [GTIndex inMemoryIndexWithRepository:repo error:&error]; index = [repo indexWithError:&error]; @@ -329,7 +329,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTNoteSpec.m b/ObjectiveGitTests/GTNoteSpec.m index 3f977df5..472fcce5 100644 --- a/ObjectiveGitTests/GTNoteSpec.m +++ b/ObjectiveGitTests/GTNoteSpec.m @@ -18,7 +18,7 @@ __block GTCommit *initialCommit; beforeEach(^{ - NSURL *fileURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:[[NSUUID alloc] init].UUIDString isDirectory:NO]; + NSURL *fileURL = [QuickSpec.current.tempDirectoryFileURL URLByAppendingPathComponent:[[NSUUID alloc] init].UUIDString isDirectory:NO]; repository = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL options:nil error:NULL]; expect(repository).notTo(beNil()); @@ -81,7 +81,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTOIDSpec.m b/ObjectiveGitTests/GTOIDSpec.m index ae9421a1..d74d22b8 100644 --- a/ObjectiveGitTests/GTOIDSpec.m +++ b/ObjectiveGitTests/GTOIDSpec.m @@ -81,7 +81,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTObjectDatabaseSpec.m b/ObjectiveGitTests/GTObjectDatabaseSpec.m index 654a06fc..33c4bf58 100644 --- a/ObjectiveGitTests/GTObjectDatabaseSpec.m +++ b/ObjectiveGitTests/GTObjectDatabaseSpec.m @@ -17,7 +17,7 @@ __block GTObjectDatabase *database; beforeEach(^{ - GTRepository *repo = self.bareFixtureRepository; + GTRepository *repo = QuickSpec.current.bareFixtureRepository; expect(repo).notTo(beNil()); database = [repo objectDatabaseWithError:NULL]; @@ -75,7 +75,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTObjectSpec.m b/ObjectiveGitTests/GTObjectSpec.m index 677b9c5d..5672ff01 100644 --- a/ObjectiveGitTests/GTObjectSpec.m +++ b/ObjectiveGitTests/GTObjectSpec.m @@ -38,7 +38,7 @@ __block GTRepository *repo; beforeEach(^{ - repo = self.bareFixtureRepository; + repo = QuickSpec.current.bareFixtureRepository; }); it(@"should fail to look up an empty string", ^{ diff --git a/ObjectiveGitTests/GTReferenceSpec.m b/ObjectiveGitTests/GTReferenceSpec.m index a3b9b402..6f51d2fe 100644 --- a/ObjectiveGitTests/GTReferenceSpec.m +++ b/ObjectiveGitTests/GTReferenceSpec.m @@ -17,7 +17,7 @@ __block GTRepository *repository; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); }); @@ -58,7 +58,7 @@ __block GTReference *reference; beforeEach(^{ - GTRepository *repository = self.bareFixtureRepository; + GTRepository *repository = QuickSpec.current.bareFixtureRepository; expect(repository).notTo(beNil()); NSError *error; @@ -125,7 +125,7 @@ }; beforeEach(^{ - bareRepository = self.bareFixtureRepository; + bareRepository = QuickSpec.current.bareFixtureRepository; }); describe(@"+referenceByLookingUpReferenceNamed:inRepository:error:", ^{ @@ -191,7 +191,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTReflogSpec.m b/ObjectiveGitTests/GTReflogSpec.m index cc4bd022..29c65a29 100644 --- a/ObjectiveGitTests/GTReflogSpec.m +++ b/ObjectiveGitTests/GTReflogSpec.m @@ -17,7 +17,7 @@ __block GTReflog *reflog; __block GTRepository *repository; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); GTBranch *branch = [repository currentBranchWithError:NULL]; @@ -57,7 +57,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTRemotePushSpec.m b/ObjectiveGitTests/GTRemotePushSpec.m index a4c4af33..bb4e4449 100644 --- a/ObjectiveGitTests/GTRemotePushSpec.m +++ b/ObjectiveGitTests/GTRemotePushSpec.m @@ -21,7 +21,7 @@ __block GTRepository *notBareRepo; beforeEach(^{ - notBareRepo = self.bareFixtureRepository; + notBareRepo = QuickSpec.current.bareFixtureRepository; expect(notBareRepo).notTo(beNil()); // This repo is not really "bare" according to libgit2 expect(@(notBareRepo.isBare)).to(beFalsy()); diff --git a/ObjectiveGitTests/GTRemoteSpec.m b/ObjectiveGitTests/GTRemoteSpec.m index 0269a3f6..8c7b6977 100644 --- a/ObjectiveGitTests/GTRemoteSpec.m +++ b/ObjectiveGitTests/GTRemoteSpec.m @@ -21,7 +21,7 @@ NSString *fetchRefspec = @"+refs/heads/*:refs/remotes/origin/*"; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); NSError *error = nil; @@ -100,7 +100,7 @@ __block NSString *remoteName; beforeEach(^{ - repository = self.bareFixtureRepository; + repository = QuickSpec.current.bareFixtureRepository; expect(@(repository.isBare)).to(beFalsy()); // yeah right repositoryURL = repository.gitDirectoryURL; NSURL *fixturesURL = repositoryURL.URLByDeletingLastPathComponent; diff --git a/ObjectiveGitTests/GTRepository+PullSpec.m b/ObjectiveGitTests/GTRepository+PullSpec.m index 77eb7712..038d1f6a 100644 --- a/ObjectiveGitTests/GTRepository+PullSpec.m +++ b/ObjectiveGitTests/GTRepository+PullSpec.m @@ -21,7 +21,7 @@ __block GTRepository *notBareRepo; beforeEach(^{ - notBareRepo = self.bareFixtureRepository; + notBareRepo = QuickSpec.current.bareFixtureRepository; expect(notBareRepo).notTo(beNil()); // This repo is not really "bare" according to libgit2 expect(@(notBareRepo.isBare)).to(beFalsy()); diff --git a/ObjectiveGitTests/GTRepository+StatusSpec.m b/ObjectiveGitTests/GTRepository+StatusSpec.m index c2ceaa9c..76f39ccc 100644 --- a/ObjectiveGitTests/GTRepository+StatusSpec.m +++ b/ObjectiveGitTests/GTRepository+StatusSpec.m @@ -22,7 +22,7 @@ NSData *testData = [@"test" dataUsingEncoding:NSUTF8StringEncoding]; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; targetFileURL = [repository.fileURL URLByAppendingPathComponent:@"main.m"]; expect(repository).notTo(beNil()); }); @@ -126,7 +126,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTRepositoryAttributesSpec.m b/ObjectiveGitTests/GTRepositoryAttributesSpec.m index e60737eb..aea5dc71 100644 --- a/ObjectiveGitTests/GTRepositoryAttributesSpec.m +++ b/ObjectiveGitTests/GTRepositoryAttributesSpec.m @@ -17,7 +17,7 @@ __block GTRepository *repository; beforeEach(^{ - repository = [self blankFixtureRepository]; + repository = [QuickSpec.current blankFixtureRepository]; }); it(@"should be able to look up attributes", ^{ diff --git a/ObjectiveGitTests/GTRepositoryCommittingSpec.m b/ObjectiveGitTests/GTRepositoryCommittingSpec.m index 8e0ffa3f..d2c68f3c 100644 --- a/ObjectiveGitTests/GTRepositoryCommittingSpec.m +++ b/ObjectiveGitTests/GTRepositoryCommittingSpec.m @@ -21,7 +21,7 @@ NSString *UUID = CFBridgingRelease(CFUUIDCreateString(NULL, UUIDRef)); CFRelease(UUIDRef); - NSURL *fileURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:UUID isDirectory:NO]; + NSURL *fileURL = [QuickSpec.current.tempDirectoryFileURL URLByAppendingPathComponent:UUID isDirectory:NO]; repository = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL options:nil error:NULL]; expect(repository).notTo(beNil()); }); @@ -56,7 +56,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTRepositoryResetSpec.m b/ObjectiveGitTests/GTRepositoryResetSpec.m index eab04871..9a113a26 100644 --- a/ObjectiveGitTests/GTRepositoryResetSpec.m +++ b/ObjectiveGitTests/GTRepositoryResetSpec.m @@ -20,7 +20,7 @@ __block NSUInteger (^countStagedFiles)(void); beforeEach(^{ - repository = [self testAppFixtureRepository]; + repository = [QuickSpec.current testAppFixtureRepository]; countStagedFiles = ^{ __block NSUInteger count = 0; @@ -58,7 +58,7 @@ describe(@"-resetToCommit:resetType:error:", ^{ beforeEach(^{ - repository = [self bareFixtureRepository]; + repository = [QuickSpec.current bareFixtureRepository]; }); it(@"should move HEAD when used", ^{ @@ -89,7 +89,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTRepositorySpec.m b/ObjectiveGitTests/GTRepositorySpec.m index 88d7571d..3ea78eaa 100644 --- a/ObjectiveGitTests/GTRepositorySpec.m +++ b/ObjectiveGitTests/GTRepositorySpec.m @@ -21,13 +21,13 @@ __block GTRepository *repository; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); }); describe(@"+initializeEmptyRepositoryAtFileURL:bare:error:", ^{ it(@"should initialize a repository with a working directory by default", ^{ - NSURL *newRepoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo"]; + NSURL *newRepoURL = [QuickSpec.current.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo"]; NSError *error; GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL options:nil error:&error]; @@ -39,7 +39,7 @@ }); it(@"should initialize a bare repository", ^{ - NSURL *newRepoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo.git"]; + NSURL *newRepoURL = [QuickSpec.current.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo.git"]; NSDictionary *options = @{ GTRepositoryInitOptionsFlags: @(GTRepositoryInitBare | GTRepositoryInitCreatingRepositoryDirectory) }; @@ -85,12 +85,12 @@ checkoutProgressCalled = YES; }; - workdirURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"temp-repo"]; + workdirURL = [QuickSpec.current.tempDirectoryFileURL URLByAppendingPathComponent:@"temp-repo"]; }); describe(@"with local repositories", ^{ beforeEach(^{ - originURL = self.bareFixtureRepository.gitDirectoryURL; + originURL = QuickSpec.current.bareFixtureRepository.gitDirectoryURL; }); it(@"should handle normal clones", ^{ @@ -208,7 +208,7 @@ describe(@"-headReferenceWithError:", ^{ it(@"should allow HEAD to be looked up", ^{ NSError *error = nil; - GTReference *head = [self.bareFixtureRepository headReferenceWithError:&error]; + GTReference *head = [QuickSpec.current.bareFixtureRepository headReferenceWithError:&error]; expect(head).notTo(beNil()); expect(error).to(beNil()); expect(head.targetOID.SHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a")); @@ -216,7 +216,7 @@ }); it(@"should fail to return HEAD for an unborn repo", ^{ - GTRepository *repo = self.blankFixtureRepository; + GTRepository *repo = QuickSpec.current.blankFixtureRepository; expect(@(repo.isHEADUnborn)).to(beTruthy()); NSError *error = nil; @@ -235,7 +235,7 @@ it(@"should return YES for a new repository", ^{ NSError *error = nil; - NSURL *fileURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"newrepo"]; + NSURL *fileURL = [QuickSpec.current.tempDirectoryFileURL URLByAppendingPathComponent:@"newrepo"]; GTRepository *newRepo = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL options:nil error:&error]; expect(newRepo).notTo(beNil()); expect(@(newRepo.isEmpty)).to(beTruthy()); @@ -381,7 +381,7 @@ describe(@"-referenceNamesWithError:", ^{ it(@"should return reference names", ^{ NSError *error = nil; - NSArray *refs = [self.bareFixtureRepository referenceNamesWithError:&error]; + NSArray *refs = [QuickSpec.current.bareFixtureRepository referenceNamesWithError:&error]; expect(refs).notTo(beNil()); expect(error).to(beNil()); @@ -395,7 +395,7 @@ it(@"should create a new tag",^{ NSError *error = nil; NSString *SHA = @"0c37a5391bbff43c37f0d0371823a5509eed5b1d"; - GTRepository *repo = self.bareFixtureRepository; + GTRepository *repo = QuickSpec.current.bareFixtureRepository; GTTag *tag = (GTTag *)[repo lookUpObjectBySHA:SHA error:&error]; GTOID *newOID = [repo OIDByCreatingTagNamed:@"a_new_tag" target:tag.target tagger:tag.tagger message:@"my tag\n" error:&error]; @@ -415,7 +415,7 @@ it(@"should fail to create an already existing tag", ^{ NSError *error = nil; NSString *SHA = @"0c37a5391bbff43c37f0d0371823a5509eed5b1d"; - GTRepository *repo = self.bareFixtureRepository; + GTRepository *repo = QuickSpec.current.bareFixtureRepository; GTTag *tag = (GTTag *)[repo lookUpObjectBySHA:SHA error:&error]; GTOID *OID = [repo OIDByCreatingTagNamed:tag.name target:tag.target tagger:tag.tagger message:@"new message" error:&error]; @@ -426,7 +426,7 @@ describe(@"move head", ^{ beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; }); //- (BOOL)moveHEADToReference:(GTReference *)reference error:(NSError **)error; @@ -576,7 +576,7 @@ describe(@"-resetToCommit:withResetType:error:", ^{ beforeEach(^{ - repository = self.bareFixtureRepository; + repository = QuickSpec.current.bareFixtureRepository; }); it(@"should move HEAD when used", ^{ @@ -654,7 +654,7 @@ };; beforeEach(^{ - repository = self.bareFixtureRepository; + repository = QuickSpec.current.bareFixtureRepository; }); it(@"should parse various revspecs", ^{ @@ -671,7 +671,7 @@ __block NSArray *branches; beforeEach(^{ - GTRepository *repository = [self testAppForkFixtureRepository]; + GTRepository *repository = [QuickSpec.current testAppForkFixtureRepository]; branches = [repository branches:NULL]; expect(branches).notTo(beNil()); }); @@ -771,7 +771,7 @@ describe(@"-calculateState:withError:", ^{ it(@"should find if the repository is mid-merge", ^{ - GTRepository *repository = [self conflictedFixtureRepository]; + GTRepository *repository = [QuickSpec.current conflictedFixtureRepository]; GTRepositoryStateType state; BOOL result; result = [repository calculateState:&state withError:NULL]; @@ -780,7 +780,7 @@ }); it(@"should return none otherwise", ^{ - GTRepository *repository = [self testAppFixtureRepository]; + GTRepository *repository = [QuickSpec.current testAppFixtureRepository]; GTRepositoryStateType state; BOOL result; result = [repository calculateState:&state withError:NULL]; @@ -791,7 +791,7 @@ describe(@"-cleanupStateWithError:", ^{ it(@"should return a repository to a pre-merge state", ^{ - GTRepository *repository = [self conflictedFixtureRepository]; + GTRepository *repository = [QuickSpec.current conflictedFixtureRepository]; GTRepositoryStateType state; BOOL result; @@ -808,7 +808,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTRepositoryStashingSpec.m b/ObjectiveGitTests/GTRepositoryStashingSpec.m index 4b5891e5..e84b55c6 100644 --- a/ObjectiveGitTests/GTRepositoryStashingSpec.m +++ b/ObjectiveGitTests/GTRepositoryStashingSpec.m @@ -17,7 +17,7 @@ __block GTRepository *repository; beforeEach(^{ - repository = self.testAppFixtureRepository; + repository = QuickSpec.current.testAppFixtureRepository; expect(repository).notTo(beNil()); }); @@ -195,7 +195,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTSignatureSpec.m b/ObjectiveGitTests/GTSignatureSpec.m index 17281a0b..4e2be146 100644 --- a/ObjectiveGitTests/GTSignatureSpec.m +++ b/ObjectiveGitTests/GTSignatureSpec.m @@ -59,7 +59,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTSubmoduleSpec.m b/ObjectiveGitTests/GTSubmoduleSpec.m index 0a25f5e3..5575c120 100644 --- a/ObjectiveGitTests/GTSubmoduleSpec.m +++ b/ObjectiveGitTests/GTSubmoduleSpec.m @@ -17,7 +17,7 @@ __block GTRepository *repo; beforeEach(^{ - repo = self.submoduleFixtureRepository; + repo = QuickSpec.current.submoduleFixtureRepository; expect(repo).notTo(beNil()); }); @@ -251,7 +251,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTTagSpec.m b/ObjectiveGitTests/GTTagSpec.m index bdbb5a5b..868496d8 100644 --- a/ObjectiveGitTests/GTTagSpec.m +++ b/ObjectiveGitTests/GTTagSpec.m @@ -18,7 +18,7 @@ beforeEach(^{ NSError *error = nil; - GTRepository *repo = self.bareFixtureRepository; + GTRepository *repo = QuickSpec.current.bareFixtureRepository; NSString *tagSHA = @"0c37a5391bbff43c37f0d0371823a5509eed5b1d"; tag = (GTTag *)[repo lookUpObjectBySHA:tagSHA error:&error]; expect(error).to(beNil()); @@ -52,7 +52,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTTimeAdditionsSpec.m b/ObjectiveGitTests/GTTimeAdditionsSpec.m index 21c64914..4ff06781 100644 --- a/ObjectiveGitTests/GTTimeAdditionsSpec.m +++ b/ObjectiveGitTests/GTTimeAdditionsSpec.m @@ -46,7 +46,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTTreeBuilderSpec.m b/ObjectiveGitTests/GTTreeBuilderSpec.m index 4c0d9a3b..0d68e6fd 100644 --- a/ObjectiveGitTests/GTTreeBuilderSpec.m +++ b/ObjectiveGitTests/GTTreeBuilderSpec.m @@ -19,7 +19,7 @@ __block GTRepository *repo; beforeEach(^{ - repo = self.bareFixtureRepository; + repo = QuickSpec.current.bareFixtureRepository; expect(repo).notTo(beNil()); }); @@ -134,7 +134,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/GTTreeSpec.m b/ObjectiveGitTests/GTTreeSpec.m index 70a1c10d..85044c47 100644 --- a/ObjectiveGitTests/GTTreeSpec.m +++ b/ObjectiveGitTests/GTTreeSpec.m @@ -19,7 +19,7 @@ __block GTTree *tree; beforeEach(^{ - GTRepository *repo = self.bareFixtureRepository; + GTRepository *repo = QuickSpec.current.bareFixtureRepository; expect(repo).notTo(beNil()); tree = (GTTree *)[repo lookUpObjectBySHA:testTreeSHA error:NULL]; @@ -124,7 +124,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/NSArray+StringArraySpec.m b/ObjectiveGitTests/NSArray+StringArraySpec.m index 757e8642..c620848d 100644 --- a/ObjectiveGitTests/NSArray+StringArraySpec.m +++ b/ObjectiveGitTests/NSArray+StringArraySpec.m @@ -102,7 +102,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/NSDataGitSpec.m b/ObjectiveGitTests/NSDataGitSpec.m index 82c4886d..c70c8c21 100644 --- a/ObjectiveGitTests/NSDataGitSpec.m +++ b/ObjectiveGitTests/NSDataGitSpec.m @@ -68,7 +68,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/NSErrorGitSpec.m b/ObjectiveGitTests/NSErrorGitSpec.m index 69217437..afd62f90 100644 --- a/ObjectiveGitTests/NSErrorGitSpec.m +++ b/ObjectiveGitTests/NSErrorGitSpec.m @@ -57,7 +57,7 @@ }); afterEach(^{ - [self tearDown]; + [QuickSpec.current tearDown]; }); QuickSpecEnd diff --git a/ObjectiveGitTests/SwiftSpec.swift b/ObjectiveGitTests/SwiftSpec.swift index 90085614..ffda1e46 100644 --- a/ObjectiveGitTests/SwiftSpec.swift +++ b/ObjectiveGitTests/SwiftSpec.swift @@ -14,7 +14,7 @@ import XCTest // “Embedded Content Contains Swift Code” is enabled). // https://github.com/Quick/Quick/issues/164 class SwiftSpec: QuickSpec { - override func spec() { + override class func spec() { expect(true).to(beTruthy()) } } From 9a0ef3b520b65cdfe14d3101af4c448bd441dc7b Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Mon, 28 Sep 2026 07:49:46 +0200 Subject: [PATCH 6/6] Fix a fixture-unzip race between parallel test processes Recent Xcode enables parallel test execution by default, running each Quick Spec class's tests in its own process. All of those processes share the same NSTemporaryDirectory() though, so they also share rootTempDirectory and, within it, the cached clean_repository directory that -setUpRepositoryFixtureIfNeeded: unzips fixtures.zip into once and reuses across specs. That caching checked for clean_repository's existence and unzipped straight into it if missing. With two processes racing, one could see the directory as soon as the other process created it (mkdir happens before the archive's contents are fully extracted) and start copying a fixture out of it before extraction reached that entry, e.g.: Couldn't copy directory Error Domain=NSCocoaErrorDomain Code=260 "The file testrepo.git couldn't be opened because there is no such file." Fix this the same way as any other read-visible-before-fully-written race: unzip into a private, uniquely named staging directory first, then publish it under clean_repository with a single atomic rename (-moveItemAtPath:toPath:error:). The shared name now only ever refers to a fully extracted directory. If another process already published clean_repository first, our move fails because the destination exists; in that case just discard the redundant staging copy and proceed, since the fixtures are already there. --- ObjectiveGitTests/QuickSpec+GTFixtures.m | 27 ++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/ObjectiveGitTests/QuickSpec+GTFixtures.m b/ObjectiveGitTests/QuickSpec+GTFixtures.m index a54270a3..45ab08b6 100644 --- a/ObjectiveGitTests/QuickSpec+GTFixtures.m +++ b/ObjectiveGitTests/QuickSpec+GTFixtures.m @@ -91,9 +91,32 @@ - (void)setUpRepositoryFixtureIfNeeded:(NSString *)repositoryName { NSString *cleanRepositoryPath = [self.rootTempDirectory stringByAppendingPathComponent:@"clean_repository"]; if (![NSFileManager.defaultManager fileExistsAtPath:cleanRepositoryPath isDirectory:nil]) { + // Parallel test execution runs each Spec class in its own process, but + // they all share the same rootTempDirectory (NSTemporaryDirectory() is + // per-user, not per-process). If two processes both see + // cleanRepositoryPath missing and unzip straight into it, one process + // can observe the directory as soon as it's created (e.g. via mkdir) + // and start copying out of it before the other process has finished + // extracting every entry, hitting "no such file" for whichever + // fixture hadn't been written yet. + // + // Avoid that by unzipping into a private, uniquely named staging + // directory first, then publishing it under cleanRepositoryPath with + // a single atomic rename. That way the shared name only ever refers + // to a fully extracted directory, never a partial one. + NSString *stagingPath = [self.rootTempDirectory stringByAppendingPathComponent:[@"clean_repository-" stringByAppendingString:NSProcessInfo.processInfo.globallyUniqueString]]; + + error = nil; + success = [self unzipFromArchiveAtPath:zippedRepositoriesPath intoDirectory:stagingPath error:&error]; + XCTAssertTrue(success, @"Couldn't unzip fixture \"%@\" from %@ to %@: %@", repositoryName, zippedRepositoriesPath, stagingPath, error); + error = nil; - success = [self unzipFromArchiveAtPath:zippedRepositoriesPath intoDirectory:cleanRepositoryPath error:&error]; - XCTAssertTrue(success, @"Couldn't unzip fixture \"%@\" from %@ to %@: %@", repositoryName, zippedRepositoriesPath, cleanRepositoryPath, error); + if (![NSFileManager.defaultManager moveItemAtPath:stagingPath toPath:cleanRepositoryPath error:&error]) { + // Another process already published cleanRepositoryPath first; + // that's fine, just discard our redundant staging copy. + [NSFileManager.defaultManager removeItemAtPath:stagingPath error:NULL]; + XCTAssertTrue([NSFileManager.defaultManager fileExistsAtPath:cleanRepositoryPath isDirectory:nil], @"Couldn't publish unzipped fixtures at %@: %@", cleanRepositoryPath, error); + } } success = [[NSFileManager defaultManager] copyItemAtPath:[cleanRepositoryPath stringByAppendingPathComponent:repositoryName] toPath:path error:&error];