Skip to content

Add AppStats unit tests, Swift package target, and README test docs#74

Merged
debugtheworldbot merged 3 commits intomainfrom
codex/generate-complete-test-cases-and-code
Mar 10, 2026
Merged

Add AppStats unit tests, Swift package target, and README test docs#74
debugtheworldbot merged 3 commits intomainfrom
codex/generate-complete-test-cases-and-code

Conversation

@debugtheworldbot
Copy link
Copy Markdown
Owner

Motivation

  • Provide regression tests for the AppStats model to ensure correct counting, decoding, and update behaviors.
  • Make the AppStats logic testable via swift test by exposing the core sources as a package target.

Description

  • Add KeyStatsTests/AppStatsTests.swift containing XCTest cases that verify initialization defaults, recording methods, scroll accumulation, display name updates, Codable round-trip, legacy otherClicks decoding behavior, and missing-field fallbacks.
  • Add a Package.swift to define a KeyStatsCore target and a KeyStatsCoreTests test target that includes AppStatsTests.swift.
  • Add Sources/KeyStatsCore/AppStats.swift as a path entry pointing at the existing KeyStats/AppStats.swift so the package target builds the app model.
  • Update README.md and README_ZH.md to document the new AppStats tests and include instructions to run them with swift test.

Testing

  • Run swift test to execute the AppStats XCTest suite.
  • All added tests in KeyStatsTests/AppStatsTests.swift passed successfully, including legacy decoding and Codable round-trip checks.
  • The package builds the KeyStatsCore target and its test target without errors when running the test command.

Codex Task

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the KeyStats project by integrating robust unit testing for the AppStats model and establishing a Swift package target for its core logic. These changes ensure the reliability and maintainability of the application's statistics tracking, providing a clear and automated way to validate its behavior across various scenarios, including data persistence and backward compatibility.

Highlights

  • Unit Tests for AppStats: Added comprehensive XCTest cases for the AppStats model, verifying initialization, recording methods, scroll accumulation, display name updates, Codable round-trip, and legacy decoding behaviors.
  • Swift Package Target: Introduced a Package.swift manifest to define KeyStatsCore and KeyStatsCoreTests targets, making the AppStats logic testable via swift test.
  • Documentation Updates: Updated README.md and README_ZH.md to include documentation and instructions for running the newly added AppStats unit tests.
Changelog
  • KeyStatsTests/AppStatsTests.swift
    • Added XCTest cases to verify AppStats initialization defaults.
    • Added tests for correct accumulation of key presses and clicks.
    • Added tests for addScrollDistance using absolute values.
    • Added tests for updateDisplayName behavior, including handling empty names.
    • Added tests for Codable round-trip preservation of fields.
    • Added tests for decoding legacy otherClicks to backfill sideBackClicks.
    • Added tests to ensure explicit side clicks take precedence over legacy otherClicks.
    • Added tests for missing fields falling back to default values during decoding.
  • Package.swift
    • Added a new Swift package manifest.
    • Defined a KeyStatsCore library product.
    • Defined a KeyStatsCore target pointing to Sources/KeyStatsCore.
    • Defined a KeyStatsCoreTests test target with AppStatsTests.swift as a source.
  • README.md
    • Added a new "Testing (AppStats)" section.
    • Documented the purpose of the AppStats tests.
    • Listed the covered test cases.
    • Provided instructions to run tests using swift test.
  • README_ZH.md
    • Added a new "测试(AppStats)" section.
    • Documented the purpose of the AppStats tests in Chinese.
    • Listed the covered test cases in Chinese.
    • Provided instructions to run tests using swift test.
  • Sources/KeyStatsCore/AppStats.swift
    • Added a path entry to include the existing KeyStats/AppStats.swift file in the KeyStatsCore package target.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces unit tests for the AppStats model, which is a great step for improving code quality and ensuring correctness. The changes also include setting up a Swift Package to make the code testable via swift test and updating the documentation.

My review focuses on a few areas:

  • A critical issue with how the AppStats.swift source file is included in the Swift Package, which will likely prevent it from building.
  • Improving the robustness of the new tests by avoiding force unwraps and magic numbers.
  • Minor convention improvements in Package.swift and formatting in the README files.

Overall, the tests are well-written and cover important cases, including legacy data migration. Addressing the feedback will make the implementation more robust and conventional.

Comment thread Sources/KeyStatsCore/AppStats.swift Outdated
@@ -0,0 +1 @@
../../KeyStats/AppStats.swift No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file appears to contain a relative path as its content, rather than being a Swift source file or a symbolic link. The Swift compiler cannot process a text file containing a path, so the package build will fail. To share the AppStats.swift source file between your Xcode project and this Swift package, you should use a symbolic link or adjust the target's path in Package.swift.

Recommended Fix (Symbolic Link):
Delete this text file and create a symlink instead:

ln -s ../../KeyStats/AppStats.swift Sources/KeyStatsCore/AppStats.swift

Alternative Fix (Package.swift):
Alternatively, you could modify your Package.swift to point directly to the source file's directory, though this might require more restructuring.

Given that the PR description states that swift test passes, it's possible this is intended to be a symlink and is being misinterpreted by Git. If so, please ensure it's committed as a symlink.

Comment on lines +77 to +82
XCTAssertEqual(decoded.keyPresses, 12)
XCTAssertEqual(decoded.leftClicks, 3)
XCTAssertEqual(decoded.rightClicks, 4)
XCTAssertEqual(decoded.sideBackClicks, 5)
XCTAssertEqual(decoded.sideForwardClicks, 6)
XCTAssertEqual(decoded.scrollDistance, 18.2, accuracy: 0.0001)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve maintainability and reduce redundancy, it's better to assert against the properties of the original object rather than using hardcoded values. This way, if you change the test data, you only need to update it in one place.

Suggested change
XCTAssertEqual(decoded.keyPresses, 12)
XCTAssertEqual(decoded.leftClicks, 3)
XCTAssertEqual(decoded.rightClicks, 4)
XCTAssertEqual(decoded.sideBackClicks, 5)
XCTAssertEqual(decoded.sideForwardClicks, 6)
XCTAssertEqual(decoded.scrollDistance, 18.2, accuracy: 0.0001)
XCTAssertEqual(decoded.keyPresses, original.keyPresses)
XCTAssertEqual(decoded.leftClicks, original.leftClicks)
XCTAssertEqual(decoded.rightClicks, original.rightClicks)
XCTAssertEqual(decoded.sideBackClicks, original.sideBackClicks)
XCTAssertEqual(decoded.sideForwardClicks, original.sideForwardClicks)
XCTAssertEqual(decoded.scrollDistance, original.scrollDistance, accuracy: 0.0001)

Comment on lines +86 to +96
let json = """
{
"bundleId": "com.test.app",
"displayName": "Test App",
"keyPresses": 2,
"leftClicks": 1,
"rightClicks": 1,
"otherClicks": 9,
"scrollDistance": 4.5
}
""".data(using: .utf8)!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using XCTUnwrap is safer than force-unwrapping (!) the result of data(using: .utf8). This prevents the test from crashing if the string cannot be converted to data and instead provides a more informative test failure.

Suggested change
let json = """
{
"bundleId": "com.test.app",
"displayName": "Test App",
"keyPresses": 2,
"leftClicks": 1,
"rightClicks": 1,
"otherClicks": 9,
"scrollDistance": 4.5
}
""".data(using: .utf8)!
let json = try XCTUnwrap("""
{
"bundleId": "com.test.app",
"displayName": "Test App",
"keyPresses": 2,
"leftClicks": 1,
"rightClicks": 1,
"otherClicks": 9,
"scrollDistance": 4.5
}
""".data(using: .utf8))

Comment on lines +106 to +117
let json = """
{
"bundleId": "com.test.app",
"displayName": "Test App",
"leftClicks": 1,
"rightClicks": 1,
"sideBackClicks": 2,
"sideForwardClicks": 3,
"otherClicks": 100,
"scrollDistance": 0
}
""".data(using: .utf8)!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using XCTUnwrap is safer than force-unwrapping (!) the result of data(using: .utf8). This prevents the test from crashing if the string cannot be converted to data and instead provides a more informative test failure.

Suggested change
let json = """
{
"bundleId": "com.test.app",
"displayName": "Test App",
"leftClicks": 1,
"rightClicks": 1,
"sideBackClicks": 2,
"sideForwardClicks": 3,
"otherClicks": 100,
"scrollDistance": 0
}
""".data(using: .utf8)!
let json = try XCTUnwrap("""
{
"bundleId": "com.test.app",
"displayName": "Test App",
"leftClicks": 1,
"rightClicks": 1,
"sideBackClicks": 2,
"sideForwardClicks": 3,
"otherClicks": 100,
"scrollDistance": 0
}
""".data(using: .utf8))

}

func testDecodeMissingFieldsFallsBackToZeroAndEmpty() throws {
let json = "{}".data(using: .utf8)!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using XCTUnwrap is safer than force-unwrapping (!) the result of data(using: .utf8). This prevents the test from crashing if the string cannot be converted to data and instead provides a more informative test failure.

Suggested change
let json = "{}".data(using: .utf8)!
let json = try XCTUnwrap("{}".data(using: .utf8))

Comment thread Package.swift
import PackageDescription

let package = Package(
name: "KeyStatsCoreTests",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's conventional for the package name to match the primary library or executable it produces. In this case, naming the package KeyStatsCore would be more aligned with standard Swift package practices, as the main product is the KeyStatsCore library.

Suggested change
name: "KeyStatsCoreTests",
name: "KeyStatsCore",

Comment thread README.md
- **UI Mode**: System tray application
- **Advantages**: No runtime installation required, ready to use on Windows 10/11 out of the box, small app size (5-10 MB)


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This added blank line creates unnecessary vertical space. Please remove it to improve readability.

Comment thread README_ZH.md
- **UI 模式**:系统托盘应用
- **优势**:无需安装运行时,Windows 10/11 开箱即用,应用体积小(5-10 MB)


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This added blank line creates unnecessary vertical space. Please remove it to improve readability.

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1ec550527

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Package.swift
@@ -0,0 +1,21 @@
// swift-tools-version:5.9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align Package.swift tools version with supported Swift range

Package.swift now requires swift-tools-version:5.9, which makes swift test fail up front on any toolchain older than Swift 5.9 even though the repository still documents Swift 5.0 as the macOS language baseline (README.md technical implementation section). Since this commit positions swift test as the regression path for AppStats, that unnecessary minimum version blocks contributors using Swift 5.0–5.8 from running the new tests.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex fix this

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
@debugtheworldbot
Copy link
Copy Markdown
Owner Author

@claude review

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
@debugtheworldbot debugtheworldbot merged commit 2b1bff8 into main Mar 10, 2026
@debugtheworldbot debugtheworldbot deleted the codex/generate-complete-test-cases-and-code branch March 10, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant