Skip to content

Fix the test target not compiling against Quick 7 and libgit2 1.x - #109

Draft
goneng wants to merge 3 commits into
gitx:masterfrom
goneng:make-the-test-target-compile
Draft

goneng wants to merge 3 commits into
gitx:masterfrom
goneng:make-the-test-target-compile

Conversation

@goneng

@goneng goneng commented Sep 21, 2026

Copy link
Copy Markdown

Why this is needed

objective-git ships 207 unit tests. None of them have run in years,
because the target they live in does not compile. CI never says so: the
Test project step has been commented out in BuildPR.yml:50 since
"Split test and archive in CI" (Feb 2025), so only Archive project
runs and a dead test target looks exactly like a healthy one.

That is not a theoretical gap. #107 fixed a stack overrun in
GTRepository+Merging.m, where a git_merge_file_input was initialized
with git_merge_file_options_init, memcpy'ing a 48-byte template over a
40-byte struct. GTRepositorySpec.m:264 calls the very method that
contained it. A test target that built would have had a real chance of
catching it, and the same class of bug can walk in again tomorrow.

This PR does not enable tests in CI and does not make the suite pass. It
makes the target build and the suite run, which is the prerequisite for
both, and it is a prerequisite for #80 as well.

What was broken

Three independent things, each hiding the next:

  1. No valid architecture. The vendored xcconfig sets
    VALID_ARCHS = x86_64 for Mac targets. The framework target
    overrides it with "x86_64 arm64"; the test target never did. On
    Apple Silicon the target produced no binary at all and the build
    died at Build input file cannot be found, before compiling a
    single source file.

  2. git_buf.asize is gone. libgit2 1.x moved the allocated size
    into reserved. The three NSDataGitSpec assertions keep their
    original meaning, because git_buf_grow still writes the allocation
    size into that field.

  3. The specs were never migrated to Quick 7. QuickSpecBegin now
    expands to + (void)spec, so self in a spec body is the spec
    class, not the running example, while the fixture helpers are
    instance methods on QuickSpec. Fourteen of these were hard errors.
    The other 79 compiled only because clang permits any known selector
    on a bare Class, and would have raised unrecognized selector sent to class at run time, so fixing only the 14 would have produced a
    target that builds and then dies on the first example.

What still blocks a green run

Worth knowing before anyone turns the CI step back on. Neither is caused
by this PR, and both are better handled separately:

  • fixtures.zip cannot be extracted by a modern ZipArchive. It holds 66
    absolute symlinks under repo-with-submodule/.git/modules/** that
    point into /Applications/GitHub.app/..., left by the GitHub for Mac
    client that produced the fixture in 2013. ZipArchive 2.6.0 rejects any
    symlink escaping the destination and aborts the whole extraction, so
    no fixture repository is ever created. Worse, the half-extracted
    directory is then treated as a valid cache by
    setUpRepositoryFixtureIfNeeded:, so the unzip is never retried.
  • Nimble's beginWith force-casts the actual value to String
    (BeginWith.swift:49), so expect(nil).to(beginWith(...)) aborts the
    whole xctest process instead of failing one example.

Test plan

  • xcodebuild -workspace ObjectiveGitFramework.xcworkspace -scheme "ObjectiveGit Mac" build-for-testing ARCHS=arm64 gives
    ** TEST BUILD SUCCEEDED **, exit 0, zero errors. On master the same
    command fails with Build input file cannot be found.
  • test-without-building then runs the suite for the first time: 207
    tests executed, where master executes none. They fail, every one of
    them traceable to the fixture extraction described above, which is
    the next thing to fix.
  • Reverting only the Quick commit and keeping the other two reproduces
    the 14 incomplete definition of type 'struct objc_class' errors, so
    each commit is doing work that is actually needed.

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.
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.
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant