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

Prevent retriggering of event actions #47

Merged
merged 27 commits into from
Feb 19, 2025
Merged

Conversation

robertherber
Copy link
Member

@robertherber robertherber commented Feb 14, 2025

  • Add multiple ways to skip event actions from triggering:
    • skipIfAlreadyTriggeredAfter?: Date; (good for initial setup but hard to use for follow-up days)
    • skipIfLargerEventRecordedAfter?: Date;
    • skipIfAlreadyTriggeredWithinMS?: number; (should be good for preventing "lower" events from triggering, for example a warning shield at 45 when 60 has already triggered)
    • skipIfLargerEventRecordedWithinMS?: number;
    • skipIfLargerEventRecordedSinceIntervalStarted?: boolean (since start of interval, for a daily monitor this resets at midnight)
    • neverTriggerBefore

Also adds more traceability:

  • a lastBlock with triggeredBy (event name in most cases) and blockedAt and blockedFamilyActivitySelectionId
  • a lastUnblock with triggeredBy and blockedAt
  • together with the shieldConfiguration as well as shieldActions a triggeredBy and updatedAt

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Enhanced device activity management with improved timing checks and condition-based execution of actions.
    • Added a reload capability for the activity center to instantly refresh displayed activity.
    • Expanded customization options for skipping actions based on specific timing criteria.
    • Introduced new test cases to verify action skipping functionality based on event triggers.
    • Added new constants for improved maintainability in user defaults handling.
    • Introduced a new blockAppsWithSelectionId method for enhanced app blocking functionality.
  • Bug Fixes

    • Ensured consistent return types in event handling functions.
  • Chores

    • Updated package version to v0.4.7 with underlying configuration and setup improvements.
    • Clarified project setup and configuration details in the contributing documentation.

Copy link
Contributor

coderabbitai bot commented Feb 14, 2025

Walkthrough

This pull request introduces several updates across various components of the project. A new rule is added to the SwiftLint configuration to disable function_parameter_count. A new test class is created with multiple methods for testing action skipping functionality. The handling of user defaults is refactored, incorporating new utility functions for event management. The TypeScript Action type is enhanced with additional optional properties for timing conditions. Furthermore, the device activity monitoring logic is updated to include a new function for conditional action execution based on timing checks. The project setup instructions are also clarified.

Changes

File(s) Summary
.swiftlint.yml Added function_parameter_count to the disabled_rules list.
example/ios/Tests/SharedTests.swift Introduced a new test class SkipActionTests with methods for testing action skipping and event comparisons.
ios/Shared.swift Refactored user defaults handling: introduced userDefaultKeyForEvent and added new functions (isHigherEvent, removePrefixIfPresent, hasHigherTriggeredEvent, shouldExecuteAction, getLastTriggeredTimeFromUserDefaults).
src/ReactNativeDeviceActivity.types.ts Extended the Action type with new optional timing properties.
src/index.ts Added reloadDeviceActivityCenter function; updated configureActions to convert Date objects to timestamps.
targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift Updated executeActionsForEvent method and added shouldExecuteAction for conditional action execution based on timing parameters.
CONTRIBUTING.md Updated instructions regarding project setup, configuration, and testing processes.
config-plugin/getAppGroupFromExpoConfig.js Modified logic to check for process.env.INTERNALLY_TEST_EXAMPLE_PROJECT.
config-plugin/withCopyTargetFolder.js Changed condition for executing main logic based on process.env.COPY_TO_TARGET_FOLDER.
example/package.json Updated scripts to include environment variables for testing purposes.
package.json Updated package version from 0.3.1 to 0.4.7.
ios/ReactNativeDeviceActivityModule.swift Updated getEvents function to return an empty dictionary instead of an empty array when no data is found.
src/ReactNativeDeviceActivityModule.ts Added blockAppsWithSelectionId method to the mockModule.
targets/ShieldAction/ShieldActionExtension.swift Updated handleAction function to use SHIELD_ACTIONS_KEY and modified unblockAllApps invocation.
targets/ShieldConfiguration/ShieldConfigurationExtension.swift Updated to use SHIELD_CONFIGURATION_KEY for retrieving shield configuration from user defaults.

Suggested reviewers

  • mfazekas

Poem

I'm a hopping rabbit, light on my feet,
Skipping through code with a rhythmic beat.
New tests and rules, all tidy and neat,
Functions refined so our events now meet.
With each change I leap, in ASCII and cheer,
Celebrating our progress with a bunny wink here!
🐰✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

pkg-pr-new bot commented Feb 14, 2025

Open in Stackblitz

npm i https://pkg.pr.new/kingstinct/react-native-device-activity@47

commit: 675e8a7

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dda0025 and efddc3d.

📒 Files selected for processing (6)
  • .swiftlint.yml (1 hunks)
  • example/ios/Tests/SharedTests.swift (1 hunks)
  • ios/Shared.swift (1 hunks)
  • src/ReactNativeDeviceActivity.types.ts (2 hunks)
  • src/index.ts (1 hunks)
  • targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Swift Test (example project)
  • GitHub Check: Expo Bundle (example project)
🔇 Additional comments (15)
targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (7)

85-89: Looks solid.

No particular issues in this newly added call; the usage of self.executeActionsForEvent is clear.


103-107: Usage is consistent.

No issues with this event-based invocation; the method call aligns well with the overall flow.


138-142: Parameter extraction is clear.

The skip-related parameters are well-defined and checked before being passed. Looks good.


144-183: Conditional logic seems appropriate.

All skip conditions are funneled through shouldExecuteAction, which simplifies the main loop.


185-189: No issues in this change.

Invocation is consistent with other event callbacks.


203-208: Flows consistently.

The approach mirrors the other event callback calls. No concerns.


223-228: Same pattern used effectively.

All event triggers now use the new logic, ensuring consistent behavior.

example/ios/Tests/SharedTests.swift (3)

80-89: Well-structured test.

This test covers boundary conditions (lower, equal, higher). Looks great.


91-99: Tests string-based event names thoroughly.

Good coverage of prefixed string scenarios.


101-120: Exercises prefix replace logic clearly.

The test ensures key variations are handled properly. Nicely done.

src/index.ts (1)

151-162: Verify date conversions for reliability.

While converting from Date to timestamp is correct, confirm that these fields are always valid Date objects. Otherwise, .getTime() may fail at runtime if a non-Date value is passed.

You could run a quick type check before calling .getTime():

 skipIfLargerEventRecordedAfter:
-  action.skipIfLargerEventRecordedAfter
-    ? action.skipIfLargerEventRecordedAfter.getTime()
-    : undefined,
+  action.skipIfLargerEventRecordedAfter instanceof Date
+    ? action.skipIfLargerEventRecordedAfter.getTime()
+    : undefined,
src/ReactNativeDeviceActivity.types.ts (1)

179-182: LGTM! Well-structured timing control properties.

The new optional properties provide granular control over action execution:

  • skipIfAlreadyTriggeredAfter: Skip if already triggered after a specific date
  • skipIfLargerEventRecordedAfter: Skip if a larger event was recorded after a specific date
  • skipIfAlreadyTriggeredWithinMS: Skip if triggered within a specific time window in milliseconds
  • skipIfLargerEventRecordedWithinMS: Skip if a larger event was recorded within a specific time window in milliseconds

Also applies to: 188-191, 197-200, 207-210, 217-220, 227-230, 241-244

ios/Shared.swift (2)

544-553: LGTM! Good extraction of key generation logic.

The function follows the single responsibility principle and maintains consistent key formatting.


555-567: LGTM! Good synchronization of user defaults.

The function correctly uses the extracted key generation logic and ensures changes are persisted immediately through CFPreferencesAppSynchronize.

.swiftlint.yml (1)

11-11: LGTM! Necessary rule adjustment.

Disabling function_parameter_count is appropriate to accommodate the new functions with multiple parameters, such as hasHigherTriggeredEvent and getLastTriggeredTimeFromUserDefaults in ios/Shared.swift.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between efddc3d and 952c616.

📒 Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • config-plugin/getAppGroupFromExpoConfig.js (1 hunks)
  • config-plugin/withCopyTargetFolder.js (1 hunks)
  • example/ios/Tests/SharedTests.swift (1 hunks)
  • example/package.json (1 hunks)
  • ios/Shared.swift (1 hunks)
  • package.json (1 hunks)
  • src/index.ts (2 hunks)
  • targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (3 hunks)
🧰 Additional context used
🪛 LanguageTool
CONTRIBUTING.md

[typographical] ~7-~7: Consider adding two commas here.
Context: ... - The entitlements and info.plist files however duplicated - to not mess with the examp...

(HOWEVER_COMMA)


[style] ~8-~8: Consider an alternative to strengthen your wording.
Context: ...to each target. I prefer this to making more changes in @bacons/xcode package which only sup...

(CHANGES_ADJUSTMENTS)


[typographical] ~9-~9: Consider adding a comma after this introductory phrase.
Context: ...ot level of each target directory. - In addition the example project contains an XCode t...

(IN_GENERAL_COMMA)


[uncategorized] ~13-~13: You might be missing the article “the” here.
Context: ... as SwiftLint. ## Prebuild To try out prebuild functionality (i.e. the config plugin) ...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[grammar] ~13-~13: Did you mean to use the possessive pronoun “its”?
Context: ... expected, but the result should not in it's full state be commited to the example p...

(IT_S_ITS)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Swift Test (example project)
  • GitHub Check: Expo Bundle (example project)
🔇 Additional comments (15)
config-plugin/getAppGroupFromExpoConfig.js (1)

12-12: LGTM!

The environment variable has been updated to use INTERNALLY_TEST_EXAMPLE_PROJECT which aligns with the changes in other configuration files.

config-plugin/withCopyTargetFolder.js (1)

5-5: LGTM!

The environment variable has been renamed to COPY_TO_TARGET_FOLDER which better describes its purpose.

targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (3)

54-95: Consider modularizing or clarifying responsibilities.

executeActionsForEvent handles multiple tasks—fetching, filtering, validating, and executing actions. For readability and testability, consider splitting out the user defaults retrieval, the filtering logic, and the action execution into smaller helper methods.


22-26: LGTM!

The function calls to executeActionsForEvent have been reformatted for better readability and consistency.

Also applies to: 40-44, 103-107, 122-126, 140-144, 160-164


75-80:

❓ Verification inconclusive

Verify milliseconds to seconds conversion in timing checks.

The code extracts timing parameters in milliseconds but may need to convert them to seconds when used with Date operations. Please verify the conversion in the shouldExecuteAction function.


🏁 Script executed:

#!/bin/bash
# Description: Search for time interval operations in the codebase
rg -A 5 'addingTimeInterval|timeIntervalSince1970'

Length of output: 2291


Action: Verify Timing Conversion Consistency in the shouldExecuteAction Function

The extracted timing parameters appear to be in milliseconds, and our search confirms that elsewhere in the code (e.g., in ios/Shared.swift) time values are converted by multiplying Date().timeIntervalSince1970 by 1000 for millisecond comparisons. Please double-check that the shouldExecuteAction function consistently applies this conversion—ensuring that comparisons against thresholds like skipIfAlreadyTriggeredAfter, skipIfLargerEventRecordedAfter, skipIfAlreadyTriggeredWithinMS, and skipIfLargerEventRecordedWithinMS are made with all time values represented in milliseconds.

src/index.ts (2)

136-138: LGTM!

The function provides a clean wrapper around the module's method.


155-166: LGTM! Proper handling of Date objects.

The function correctly transforms Date objects to timestamps before storing in user defaults, which is essential for proper serialization and comparison of dates.

ios/Shared.swift (6)

544-553: LGTM! Clean key generation logic.

The function effectively generates user defaults keys with proper handling of optional event names.


555-567: LGTM! Proper timestamp handling and synchronization.

The function correctly:

  • Converts current time to milliseconds
  • Uses the extracted key generation logic
  • Ensures preferences are synchronized

569-575: Consider adding input validation.

The function correctly handles both numeric and string comparisons, but could benefit from additional error handling.


577-583: Consider adding input validation.

The function correctly handles prefix removal but could benefit from input validation.


585-616: Consider adding logging for better debugging.

The function correctly handles event timing and retrieval but could benefit from additional logging.


693-706: LGTM! Clean implementation.

The function effectively retrieves and type-casts the stored timestamp.

example/package.json (1)

6-11: LGTM! Proper environment variable configuration.

The scripts correctly set the required environment variables for testing the example project.

package.json (1)

3-3: Version Bump Verified
The version field has been updated to "0.4.0", which aligns with the new event handling features introduced in this PR. Please ensure this version bump is also reflected in the changelog and release documentation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🔭 Outside diff range comments (1)
targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (1)

54-99: 🧹 Nitpick (assertive)

Consider extracting config-key generation.
The logic building the key string is elegantly handled, but you might further unify or test that logic in a separate helper, especially if used elsewhere.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 952c616 and 734dc52.

📒 Files selected for processing (6)
  • example/ios/Tests/SharedTests.swift (1 hunks)
  • ios/ReactNativeDeviceActivityModule.swift (0 hunks)
  • ios/Shared.swift (1 hunks)
  • package.json (1 hunks)
  • src/ReactNativeDeviceActivity.types.ts (2 hunks)
  • targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (3 hunks)
💤 Files with no reviewable changes (1)
  • ios/ReactNativeDeviceActivityModule.swift
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Swift Test (example project)
  • GitHub Check: Expo Bundle (example project)
🔇 Additional comments (15)
package.json (1)

3-3: Version Bump Reflects New Feature Changes

The version has been updated from "0.3.1" to "0.4.1" to align with the new event retrigger prevention mechanisms introduced in this PR. This bump is appropriate to signal backwards-incompatible changes or new functionality to package consumers.

src/ReactNativeDeviceActivity.types.ts (6)

189-193: Repeat recommendation to provide doc comments.
These newly added properties would benefit from clear explanations to guide downstream usage.


199-203: Repeat recommendation to provide doc comments.
Remember to detail usage scenarios and valid ranges for the skip conditions.


210-214: Repeat recommendation to provide doc comments.
Including references or examples on how these properties interact with each other might be helpful.


221-225: Repeat recommendation to provide doc comments.
Ensure the structure and expected data types are clarified.


231-235: Repeat recommendation to provide doc comments.
Clear usage guidelines reduce the risk of misuse or confusion.


247-251: Repeat recommendation to provide doc comments.
Accurate inline descriptions help keep documentation in sync with the code.

ios/Shared.swift (2)

555-565: Confirm user defaults’ suite availability at runtime.
If userDefaults is nil (e.g., missing appGroup), this call will silently fail. Safely handle nil to avoid data loss.


618-712: Double-check time interval calculations in milliseconds.
The code correctly multiplies timeIntervalSince1970 by 1000, but ensure all interplay between millisecond logic and second-based APIs (e.g., Date) is consistent to avoid off-by-thousand errors.

targets/ActivityMonitorExtension/DeviceActivityMonitorExtension.swift (6)

22-27: Well-structured call to executeActionsForEvent.
The new parameter eventName is set to nil, aligning with the intervalDidStart logic. Looks consistent.


40-45: Consistent usage of executeActionsForEvent.
Likewise, passing nil for eventName matches the intervalDidEnd behavior.


107-112: Proper invocation with event-based key.
This ensures the correct action set is retrieved for threshold-based events.


126-131: Good consistency for warnings.
Again, ensuring eventName is nil when no specific event is triggered.


144-149: Uniform approach to action execution.
Maintains clarity: separate calls for each of the “WillEndWarning” states.


164-169: Aligned with event-based logic.
The passing of event.rawValue ensures no mismatch in user defaults or code references.

@robertherber robertherber changed the title Prevent retriggering Prevent retriggering of event actions Feb 15, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e7a65d and acdb4aa.

📒 Files selected for processing (2)
  • package.json (1 hunks)
  • src/index.ts (4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/index.ts

[error] 302-305: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 312-315: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 319-319: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Swift Test (example project)
  • GitHub Check: Expo Bundle (example project)
🔇 Additional comments (4)
src/index.ts (3)

155-169: LGTM! Proper handling of timing-related properties.

The implementation correctly converts Date objects to timestamps while safely handling undefined values.


399-400: LGTM! Good use of constants for string literals.

Centralizing these string literals improves maintainability and reduces the risk of typos.


402-417: LGTM! Good tracking of shield updates.

The changes properly track shield updates with timestamps and source information.

package.json (1)

3-3: LGTM! Version bump reflects new features.

The version update to 0.4.6 aligns with the new features for preventing event retriggering.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🔭 Outside diff range comments (1)
ios/Shared.swift (1)

62-123: 🧹 Nitpick (assertive)

Consider refactoring large aggregator function
The executeAction function handles multiple distinct responsibilities (sleep intervals, user defaults, optional app blocking, etc.) and relies on synchronous waits. Blocking the main thread can degrade user experience, especially on iOS. Consider splitting out sub-operations or using async calls.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 137ce51 and 675e8a7.

📒 Files selected for processing (2)
  • example/ios/Tests/SharedTests.swift (1 hunks)
  • ios/Shared.swift (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Swift Test (example project)
  • GitHub Check: Expo Bundle (example project)
🔇 Additional comments (14)
ios/Shared.swift (7)

15-16: Use constants for user defaults keys
Defining these constants is a good practice that improves maintainability and clarity when referencing user defaults throughout the code.


28-51: Verify logic of storing shield data
This function retrieves the dictionary from a key that includes the shieldId (e.g. "shieldConfiguration_\(shieldId)"), but then stores it under a general "SHIELD_CONFIGURATION_KEY". Ensure this isn’t inadvertently overwriting configurations for other shields. If unintentional, consider persisting the updated dictionary under the same key.


584-593: Validate or sanitize keys
If unexpected characters appear in activityName, callbackName, or eventName, they could collide with other user defaults keys. This was flagged previously as a potential concern.


609-615: Check string comparison edge cases
When numeric parsing fails, the fallback to localizedCompare might produce counterintuitive ordering for certain prefixed strings (e.g., “prefix_5” vs. “prefix_10”). If that’s the intended behavior, document it.


617-623: Minimal prefix remover
removePrefixIfPresent is concise. If performance in repeated calls is a concern, you might store or reuse the result, but otherwise looks good.


625-656: Potential performance overhead
hasHigherTriggeredEvent iterates over the entire user defaults dictionary. In large-scale usage, consider caching or indexing to avoid repeated full scans.


762-775: Nil handling in last triggered time
Returning nil from getLastTriggeredTimeFromUserDefaults can risk repeated triggers if the calling code doesn’t handle it. As previously suggested, returning a sentinel (like 0 or -1) might make the logic safer.

example/ios/Tests/SharedTests.swift (7)

117-155: Correct skip logic test
testShouldSkipIfAlreadyTriggeredAfter straightforwardly confirms skip behavior when the last trigger time is beyond a threshold. Good coverage.


199-240: Verifies larger event handling
testShouldSkipIfLargerTriggeredAfter ensures that if a higher event is logged after a certain time, the code properly skips. Logic looks correct.


242-285: Time-based skip
testSkipIfLargerTriggeredWithinMS is a good test of restricting a lower event. Adding a test for exactly the edge time (e.g., 100ms) may clarify boundary conditions.


287-337: Interval-based logic
testSkipIfLargerTriggeredAfterIntervalStarted checks whether a larger event blocks triggers after an interval’s start. Great scenario coverage.


339-347: Numeric comparisons
testIsHigherEventNum confirms numeric ordering. Looks correct and matches the intended logic for numeric event names.


349-357: String comparison vs. numeric
testIsHigherEventString shows “prefix_5” is higher than “prefix_10” lexicographically. If you genuinely intend this difference from numeric ordering, add a comment clarifying.


359-378: Checks prefix removal
testReplaceText nicely verifies removePrefixIfPresent with multiple inputs, including empty. This coverage is strong.

@robertherber robertherber merged commit d535124 into main Feb 19, 2025
11 checks passed
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