-
Notifications
You must be signed in to change notification settings - Fork 1
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
[ECO-5132] Added typing tests #217
base: 114-tests
Are you sure you want to change the base?
Conversation
WalkthroughThe pull request introduces enhancements to the typing indicators functionality in the AblyChat framework. The changes focus on improving the Changes
Assessment against linked issues
Possibly related PRs
Suggested reviewers
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
Sources/AblyChat/DefaultTyping.swift (2)
9-9
: Fix typo in property name.The property name contains a typo: "Presense" should be "Presence".
- private let maxPresenseGetRetryDuration: TimeInterval // Max duration as specified in CHA-T6c1 + private let maxPresenceGetRetryDuration: TimeInterval // Max duration as specified in CHA-T6c1
242-252
: Prevent memory leaks in test subscriptions.The test subscription arrays can grow indefinitely as new subscriptions are added. Consider adding cleanup logic to remove terminated subscriptions.
Add a method to clean up terminated subscriptions:
private func cleanupTerminatedSubscriptions() { testStartTypingEventSubscriptions.removeAll(where: { $0.isTerminated }) testStopTypingEventSubscriptions.removeAll(where: { $0.isTerminated }) testPresenceGetTypingEventSubscriptions.removeAll(where: { $0.isTerminated }) testPresenceGetRetryTypingEventSubscriptions.removeAll(where: { $0.isTerminated }) }Call this method before adding new subscriptions in each
testsOnly_subscribeTo*
method.Tests/AblyChatTests/DefaultRoomTypingTests.swift (3)
298-298
: Implement missing test for CHA-T6c2 specification.The test
ifMultiplePresenceEventsReceivedThenOnlyTheLatestEventIsEmitted
is currently unimplemented.Would you like me to help implement this test case? I can provide a complete implementation that verifies only the latest event is emitted when multiple presence events are received.
268-268
: Document the rationale for the arbitrary timeout value.The comment mentions the timeout value is arbitrary and references an issue. Consider adding more context about why this specific value was chosen.
- let maxPresenseGetRetryDuration = 3.0 // arbitrary, TODO: improve https://github.com/ably/ably-chat-swift/issues/216 + let maxPresenseGetRetryDuration = 3.0 // Chosen to balance between quick test execution and reliable presence get retries + // TODO: Make this configurable or determine dynamically - https://github.com/ably/ably-chat-swift/issues/216
133-134
: Extract magic numbers into named constants.The timeout value of 0.5 seconds is hardcoded without explanation. Consider extracting this and other similar values into named constants with clear documentation.
+ // Default timeout is 5 seconds, using 0.5 for faster test execution + private static let testTimeout: TimeInterval = 0.5 + - let timeout = 0.5 // default is 5 (seconds) + let timeout = Self.testTimeout
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
Sources/AblyChat/DefaultTyping.swift
(5 hunks)Tests/AblyChatTests/DefaultRoomTypingTests.swift
(1 hunks)Tests/AblyChatTests/Helpers/Helpers.swift
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (12)
- GitHub Check: Example app, tvOS (Xcode 16)
- GitHub Check: Example app, iOS (Xcode 16)
- GitHub Check: Example app, macOS (Xcode 16)
- GitHub Check: Xcode, tvOS (Xcode 16)
- GitHub Check: Xcode,
release
configuration, tvOS (Xcode 16) - GitHub Check: Xcode, iOS (Xcode 16)
- GitHub Check: SPM,
release
configuration (Xcode 16) - GitHub Check: SPM (Xcode 16)
- GitHub Check: Xcode,
release
configuration, iOS (Xcode 16) - GitHub Check: Xcode, macOS (Xcode 16)
- GitHub Check: Xcode,
release
configuration, macOS (Xcode 16) - GitHub Check: Xcode, tvOS (Xcode 16)
🔇 Additional comments (1)
Sources/AblyChat/DefaultTyping.swift (1)
Line range hint
43-82
: Consider potential race condition in presence get retry logic.The retry logic uses a shared
totalElapsedTime
variable that could be affected by concurrent presence get operations. Consider using a dedicated task for managing retries.Consider refactoring the retry logic into a dedicated async task that can be cancelled when needed. This would help prevent race conditions and make the retry state more manageable.
ddb3e18
to
3fdad4d
Compare
612bbc8
to
5466b2f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
Sources/AblyChat/DefaultTyping.swift (1)
Line range hint
43-82
: Ensure Retry Logic Correctly Respects Maximum Retry DurationIn the retry loop for
presence.get()
, verify that thetotalElapsedTime
calculation correctly accounts for the delays, including jitter, and that the loop exits after reachingmaxPresenceGetRetryDuration
.Review and adjust the calculation of
totalElapsedTime
to ensure it accurately reflects the accumulated wait times. This ensures the retry mechanism adheres to the specified maximum duration.
🧹 Nitpick comments (7)
Tests/AblyChatTests/DefaultRoomTypingTests.swift (6)
25-52
: Ensure Proper Synchronization When Testing Attachment StateIn
retrieveCurrentlyTypingClientIDsWhileAttaching()
, the test sets up an attaching state and waits for the room to become attaching before callingdefaultTyping.get()
. To prevent flaky tests, ensure that the test reliably waits for the expected state.Consider adding explicit synchronization or wait mechanisms to ensure the room status is in the attaching state before proceeding. This can improve the reliability of the test.
122-149
: Potential Race Condition in Timing-Sensitive TestIn
usersMayConfigureTimeoutForTyping()
, the test checks if the typing stopped event is emitted after a custom timeout interval. Timing-based tests can lead to flaky results due to execution environment variability.Consider using mock timers or expectations to control the timing more deterministically. This approach can enhance the reliability of the test across different environments.
194-217
: Adjust Tolerance for Timing ComparisonIn
ifTypingIsAlreadyInProgressThenTimeoutIsExtended()
, the test compares intervals using a tolerance of0.1
. Due to potential execution speed variations, consider increasing the tolerance to prevent intermittent test failures.Adjust the tolerance value to a higher number, such as
0.2
, or utilize mock timers for better reliability in timing comparisons.
241-259
: Ensure Proper Cleanup of Subscriptions in TestsIn
whenPresenceEventReceivedClientWillPerformPresenceGet()
, verify that any subscriptions or event listeners are properly cleaned up after the test to prevent side effects on other tests.Add code to unsubscribe or cancel any ongoing subscriptions at the end of the test. This practice ensures test isolation and reliability.
263-293
: Assist with Implementing the Presence Get Retry TestThe test
ifPresenceGetFailsItShallBeRetriedUsingBackoffWithJitter()
includes a TODO comment referencing issue #216.Would you like assistance in implementing this test case? I can help draft the test code or provide guidance on handling the retry logic with backoff and jitter.
297-300
: Complete the Test Implementation for Multiple Presence EventsThe test
ifMultiplePresenceEventsReceivedThenOnlyTheLatestEventIsEmitted()
is marked as TODO.Do you need help in implementing this test? I can assist in writing the test code to verify that only the latest typing event is emitted when multiple presence events are received.
Sources/AblyChat/DefaultTyping.swift (1)
236-282
: Organize Test-Only Code for Better MaintainabilityThe test-only code under
#if DEBUG
includes several subscription methods and structures. For improved maintainability, consider organizing these methods together and providing clear documentation of their purpose.Grouping the test-only code into an extension or a separate file (if appropriate) can enhance code readability and maintenance.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
Sources/AblyChat/DefaultTyping.swift
(5 hunks)Tests/AblyChatTests/DefaultRoomTypingTests.swift
(1 hunks)Tests/AblyChatTests/Helpers/Helpers.swift
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- Tests/AblyChatTests/Helpers/Helpers.swift
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: Example app, tvOS (Xcode 16)
- GitHub Check: Xcode, tvOS (Xcode 16)
- GitHub Check: Example app, iOS (Xcode 16)
- GitHub Check: Xcode, iOS (Xcode 16)
- GitHub Check: Example app, macOS (Xcode 16)
- GitHub Check: Xcode, macOS (Xcode 16)
- GitHub Check: SPM (Xcode 16)
- GitHub Check: Xcode,
release
configuration, tvOS (Xcode 16) - GitHub Check: Xcode,
release
configuration, iOS (Xcode 16) - GitHub Check: Xcode,
release
configuration, macOS (Xcode 16) - GitHub Check: SPM,
release
configuration (Xcode 16)
🔇 Additional comments (9)
Tests/AblyChatTests/DefaultRoomTypingTests.swift (5)
9-21
: Good Coverage for Retrieving Typing Client IDsThe test
retrieveCurrentlyTypingClientIDs()
correctly verifies that thedefaultTyping.get()
method retrieves the list of currently typing client IDs. The use of mock presence with predefined members ensures the test is reliable and effective.
56-95
: Accurate Error Handling in Failure ScenariosThe test
retrieveCurrentlyTypingClientIDsWhileAttachingWithFailure()
correctly handles exceptions when attachment fails. The error handling in lines 82~ to 91~ captures and asserts the expected status code and error code appropriately.
97-118
: Proper Validation of Error Handling When Room Is in Invalid StateThe test
failToRetrieveCurrentlyTypingClientIDsWhenRoomInInvalidState()
effectively verifies that an error is thrown when attempting to retrieve typing client IDs while the room is in an invalid state. The assertions correctly check for the expected error conditions.
156-189
: Effective Testing of Start and Stop Typing IndicatorsThe test
usersMayIndicateThatTheyHaveStartedOrStoppedTyping()
effectively verifies that the typing indicators work as expected when starting and stopping typing. The assertions confirm that the typing client IDs are correctly updated.
221-237
: Comprehensive Test for Subscribing to Typing EventsThe test
usersMaySubscribeToTypingEvents()
successfully verifies that subscribing to typing events works and that the correct data is received. The use of subscriptions ensures that typing events are emitted and captured as expected.Sources/AblyChat/DefaultTyping.swift (4)
12-18
: ConfigurablemaxPresenceGetRetryDuration
in InitializerThe initializer for
DefaultTyping
now accepts themaxPresenceGetRetryDuration
parameter with a default value of30.0
. This change enhances configurability and allows for better control over the retry mechanism.
75-79
: Proper Emission of Test Events During Retry AttemptsThe code under
#if DEBUG
emits test events during retry attempts. This practice is appropriate for testing purposes.Ensure that these test-only events are properly guarded and do not impact production code.
173-177
: Test Events Emitted When Stopping Typing IndicatorsIn the
stop()
method, test events are emitted under#if DEBUG
when typing is stopped. This aids in testing the stop functionality.
227-231
: Test Events Emitted When Starting Typing IndicatorsSimilarly, in the
startTyping()
method, test events are emitted under#if DEBUG
when typing starts. This facilitates testing the start functionality.
5466b2f
to
267694d
Compare
Spec coverage test issue - ably/specification#269 |
267694d
to
50dbbe6
Compare
50dbbe6
to
3e11ea0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
Sources/AblyChat/DefaultTyping.swift (2)
237-282
: Enhance documentation for test-only APIs.The test infrastructure is well-organized, but the documentation could be more descriptive about the purpose and usage of each subscription type.
Apply this diff to enhance the documentation:
#if DEBUG - /// The `DefaultTyping` emits a `TestTypingEvent` each time ``start`` or ``stop`` is called. + /// Represents a typing-related test event with a timestamp. + /// Used to track when various typing-related operations occur during testing. internal struct TestTypingEvent: Equatable { internal let timestamp = Date() } - /// Subscription of typing start events for testing purposes. + /// Collection of subscriptions that receive events when typing starts. + /// These events are emitted after successfully entering presence. private var testStartTypingEventSubscriptions: [Subscription<TestTypingEvent>] = [] - /// Subscription of typing stop events for testing purposes. + /// Collection of subscriptions that receive events when typing stops. + /// These events are emitted after successfully leaving presence. private var testStopTypingEventSubscriptions: [Subscription<TestTypingEvent>] = [] - /// Subscription of presence get events for testing purposes. + /// Collection of subscriptions that receive events when presence.get() succeeds. + /// These events are emitted after successfully retrieving the presence set. private var testPresenceGetTypingEventSubscriptions: [Subscription<TestTypingEvent>] = [] - /// Subscription of retry presence get events for testing purposes. + /// Collection of subscriptions that receive events when presence.get() fails and is retried. + /// These events are emitted before each retry attempt. private var testPresenceGetRetryTypingEventSubscriptions: [Subscription<TestTypingEvent>] = []
285-287
: Document the rationale for @unchecked Sendable conformance.Add documentation explaining why the conformance is needed and why it's safe to use @unchecked.
Apply this diff:
#if DEBUG +/// Conformance to Sendable is required for test-only features. +/// Using @unchecked because the class contains mutable state that is only accessed +/// in a controlled manner through test-only methods. extension DefaultTyping: @unchecked Sendable {} #endif
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
Sources/AblyChat/DefaultTyping.swift
(5 hunks)Tests/AblyChatTests/DefaultRoomTypingTests.swift
(1 hunks)Tests/AblyChatTests/Helpers/Helpers.swift
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- Tests/AblyChatTests/Helpers/Helpers.swift
- Tests/AblyChatTests/DefaultRoomTypingTests.swift
🔇 Additional comments (4)
Sources/AblyChat/DefaultTyping.swift (4)
9-9
: Fix typo in property name and enhance documentation.The property name has a typo: "Presense" should be "Presence". Additionally, consider adding more descriptive documentation using Swift's documentation comments.
Apply this diff:
-private let maxPresenceGetRetryDuration: TimeInterval // Max duration as specified in CHA-T6c1 +/// Maximum duration to retry presence get operations when they fail. +/// Specification: CHA-T6c1 +private let maxPresenceGetRetryDuration: TimeInterval
Line range hint
43-82
: LGTM! Well-implemented retry mechanism.The retry logic is well-implemented with:
- Configurable maximum retry duration
- Exponential backoff with jitter
- Clear error logging
- Proper test instrumentation
173-177
: LGTM! Test instrumentation properly added.Test event emission is correctly placed after the presence leave operation and properly guarded with DEBUG flag.
227-231
: LGTM! Test instrumentation properly added.Test event emission is correctly placed after the timer setup and properly guarded with DEBUG flag.
Closes #140
Summary by CodeRabbit
New Features
Tests
Improvements