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

[ECO-4952] Start implementing room lifecycle spec #54

Open
wants to merge 1 commit into
base: convention-for-test-only-apis
Choose a base branch
from

Conversation

lawrence-forooghian
Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian commented Sep 18, 2024

Note: This PR is based on top of #72; please review that one first.

This is based on ably/specification#200 at b4a495e. It’s generated some questions, which I’ve asked on that PR.

Note that the spec has been through a few revisions since I started implementing this; I’ve tried to keep everything in sync but some older stuff might still be accidentally there.

I’ve implemented most of the specified behaviour for the ATTACH, DETACH, and RELEASE operations. I have not yet implemented RETRY since it’s quite different to those three and I wanted to get eyes on this first chunk of work; have created #51 for implementing it.

Of the operations that I have implemented, I have not implemented the following (this is accurately reflected by the @spec… tags in the tests):

The room lifecycle manager introduced by this commit is currently a standalone object, which is not integrated with the rest of the SDK. I’ve created #47 for doing this integration work.

The @spec… tags are based on the on the JS rules @ 8c9ce8b, but I camel-cased them and also decided that:

  • if a test doesn't relate to a spec point, it doesn't need any markers
  • there should be a way to know that a spec point is tested across multiple tests
  • there should be a way of marking a spec point as implemented but not tested (so that can show up differently in reporting; important given that we’re also going to use this report as a to-do list of what still needs to be implemented)

Part of #28.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced new error codes for improved error handling in the chat SDK.
    • Added a new section in the contribution guidelines for better test documentation related to SDK features.
    • Implemented a RoomLifecycleManager to manage chat room contributor states effectively.
    • Added a SimpleClock protocol to facilitate asynchronous task management in testing.
    • Introduced a mock implementation of RoomLifecycleContributorChannel for testing purposes.
  • Bug Fixes

    • Enhanced error reporting for attachment and detachment failures within the chat SDK.
  • Tests

    • Added comprehensive unit tests for the RoomLifecycleManager to ensure robust lifecycle management of chat rooms.
    • Introduced mock implementations to facilitate controlled testing scenarios.
    • Improved assertion capabilities in the testing framework for better error handling validation.

Copy link

coderabbitai bot commented Sep 18, 2024

Warning

Rate limit exceeded

@lawrence-forooghian has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 50 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Files that changed from the base of the PR and between a4d3c52 and 608f43e.

Walkthrough

The pull request introduces significant enhancements to the AblyChat SDK, focusing on room lifecycle management, improved error handling, and structured testing practices. Key updates include the addition of new error codes to the ChatError enum, the implementation of a RoomLifecycleManager for managing chat room states, and the introduction of testing guidelines in CONTRIBUTING.md. These changes improve clarity and organization within the codebase, particularly regarding chat room features and error reporting.

Changes

File Path Change Summary
CONTRIBUTING.md Added guidelines for testing related to Chat SDK features, including new tags for test attribution and referencing spec item identifiers.
Sources/AblyChat/Errors.swift Enhanced ChatError enum with new error codes for attachment and detachment failures, and updated error handling mechanisms to provide clearer messages and underlying error information.
Sources/AblyChat/RoomFeature.swift Introduced a new internal enumeration RoomFeature to categorize chat room capabilities.
Sources/AblyChat/RoomLifecycleManager.swift Implemented RoomLifecycleManager to manage chat room contributor lifecycles, including attachment and detachment operations with state management and error handling.
Sources/AblyChat/SimpleClock.swift Added SimpleClock protocol for asynchronous task management, facilitating testing without relying on actual delays.
Tests/AblyChatTests/Helpers/Helpers.swift Modified assertIsChatError function to include a cause parameter for enhanced error validation.
Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift Created MockRoomLifecycleContributorChannel class for testing room lifecycle management.
Tests/AblyChatTests/Mocks/MockSimpleClock.swift Implemented MockSimpleClock for testing the SimpleClock protocol without actual delays.
Tests/AblyChatTests/RoomLifecycleManagerTests.swift Added comprehensive unit tests for RoomLifecycleManager to validate lifecycle management operations.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • maratal: Familiar with the chat SDK and its lifecycle management.
  • umair-ably: Experienced in error handling and reporting within the SDK.

🐰 "In the chat room where bunnies play,
New lifecycles bloom, brightening the day.
With errors caught and tests so neat,
Our code hops forward, a joyful feat!"
🌼


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 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

@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 and nitpick comments (6)
Sources/AblyChat/Errors.swift (2)

37-55: Address the TODOs regarding status code mappings

The statusCode property currently includes TODO comments indicating that the status codes are guesses and need revisiting once the specification questions are resolved. Finalizing these status codes based on the latest specification is crucial for accurate error handling.

Would you like assistance in updating these status codes according to the latest specification, or should we open a GitHub issue to track this task?


187-190: Document the use of NSUnderlyingErrorKey for error causation

The TODO comment suggests that using NSUnderlyingErrorKey to populate cause might be an implementation detail. It's important to document this behavior to clarify how the cause is set in ARTErrorInfo.

Shall I assist in drafting documentation for this behavior or open a GitHub issue to ensure it is addressed?

Sources/AblyChat/RoomLifecycleManager.swift (2)

117-118: Implement asynchronous behavior as per CHA-RL1h5

The TODO comment indicates that the asynchronous aspect of CHA-RL1h5 is yet to be implemented. This is important for proper adherence to the room lifecycle specification.

Would you like assistance in implementing the asynchronous behavior as per the specification, or should we open a GitHub issue to track this task?


205-205: Determine the correct wait time for retries

The TODO comment questions the appropriate wait time before retrying detach operations. Defining an optimal retry interval is important to balance performance and resource utilization.

Shall I help in determining the suitable wait time based on best practices or the latest specification, or should we open a GitHub issue to address this?

Tests/AblyChatTests/RoomLifecycleManagerTests.swift (2)

487-487: Clarify error source in detachment failure test

The TODO comment raises a question about whether to use errorReason or the error thrown by the contributor's detach call. Resolving this is important for accurate testing of error handling.

Would you like assistance in determining the correct error source according to the specification for this test case, or should we open a GitHub issue to track this question?


503-504: Address the untested spec point CHA-RL2h2

The comment indicates difficulty in testing the specification point CHA-RL2h2 due to concurrency issues. It's important to find a way to test this to ensure full coverage.

Can I help devise a testing strategy to cover this spec point, perhaps by using synchronization primitives or mock objects to control concurrency, or should we open a GitHub issue to address this challenge?

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9014b0c and 5532087.

Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
Additional context used
LanguageTool
CONTRIBUTING.md

[style] ~40-~40: Consider removing “of” to be more concise
Context: ...> of n test cases which, together, test all of the functionality documented in the spec it...

(ALL_OF_THE)


[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[style] ~43-~43: To form a complete sentence, be sure to include a subject or ‘there’.
Context: ... test this spec item. <spec-item-id> should be a spec item identifier such as `CHA-...

(MISSING_IT_THERE)


[misspelling] ~73-~73: Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’.
Context: ...a spec point. It must be accompanied by a explanation of why this spec point is n...

(EN_A_VS_AN)

Additional comments not posted (6)
Sources/AblyChat/RoomFeature.swift (1)

1-8: Well-defined RoomFeature enum

The RoomFeature enum clearly enumerates the features offered by a chat room, enhancing code clarity and maintainability.

Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1)

4-10: Appropriate use of actor for MockSimpleClock

The MockSimpleClock actor correctly records sleep durations without causing actual delays, which is suitable for testing asynchronous code. The use of an actor ensures thread-safe access to sleepCallArguments.

Sources/AblyChat/SimpleClock.swift (1)

1-7: SimpleClock protocol is well-defined

The SimpleClock protocol provides a useful abstraction for sleeping tasks, enabling mocking in tests due to the absence of the Swift Clock type in older OS versions.

Tests/AblyChatTests/Helpers/Helpers.swift (1)

8-16: Enhancement: Added 'cause' parameter to assertIsChatError

The inclusion of the cause parameter allows for more precise testing of nested errors, improving the accuracy of error assertions.

Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1)

4-95: Comprehensive mock implementation for RoomLifecycleContributorChannel

The MockRoomLifecycleContributorChannel provides a flexible and robust mock for testing channel lifecycle behaviors. The use of enums to define behavior and results allows for versatile testing scenarios, and the actor model ensures thread safety.

Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1)

695-703: Confirm wait time behavior for failed contributors during release

The TODO comment questions whether the wait should still occur when a contributor enters the FAILED state during release, as per spec CHA-RL3f.

Let's verify the expected behavior according to the specification. Based on CHA-RL3f, it's important to confirm whether the wait time applies in this scenario.

Would you like me to research the specification further to clarify this point, or should we open a GitHub issue to resolve this ambiguity?

Tests/AblyChatTests/Helpers/Helpers.swift Outdated Show resolved Hide resolved
CONTRIBUTING.md Outdated Show resolved Hide resolved
CONTRIBUTING.md Outdated Show resolved Hide resolved
CONTRIBUTING.md Show resolved Hide resolved
CONTRIBUTING.md Outdated Show resolved Hide resolved
Sources/AblyChat/RoomLifecycleManager.swift Outdated Show resolved Hide resolved
Sources/AblyChat/RoomLifecycleManager.swift Show resolved Hide resolved
Sources/AblyChat/RoomLifecycleManager.swift Outdated Show resolved Hide resolved
Sources/AblyChat/RoomLifecycleManager.swift Outdated Show resolved Hide resolved
@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch 2 times, most recently from b27744c to e940d8b Compare September 18, 2024 18:33
Copy link

@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.

Caution

Inline review comments failed to post

Actionable comments posted: 4

Outside diff range and nitpick comments (1)
CONTRIBUTING.md (1)

73-73: Typographical Correction: Remove Redundant Words

Consider removing "of" to make the sentence more concise.

Suggested change:

- It must be accompanied by an explanation of why this spec point is not tested.
+ It must be accompanied by an explanation why this spec point is not tested.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5532087 and b27744c.

Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
Files skipped from review due to trivial changes (1)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift
Files skipped from review as they are similar to previous changes (5)
  • Sources/AblyChat/RoomFeature.swift
  • Sources/AblyChat/SimpleClock.swift
  • Tests/AblyChatTests/Helpers/Helpers.swift
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift
Additional context used
Learnings (1)
Sources/AblyChat/RoomLifecycleManager.swift (4)
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:265-266
Timestamp: 2024-09-18T18:29:10.329Z
Learning: In `RoomLifecycleManager.swift`, the use of `try!` with `await` for `clock.sleep` is intentional due to reasons outlined in the associated GitHub issue. Do not suggest changing this usage unless the issue is resolved.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:262-262
Timestamp: 2024-09-18T18:29:03.379Z
Learning: When a TODO comment references an associated GitHub issue, recognize that the issue is being tracked and avoid suggesting fixes that are already planned.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#9
File: Sources/AblyChat/RoomStatus.swift:3-33
Timestamp: 2024-08-28T13:01:11.701Z
Learning: When reviewing code, avoid commenting on TODOs that already have a linked GitHub issue, as per the user's preference.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:122-124
Timestamp: 2024-09-18T18:29:39.415Z
Learning: In `RoomLifecycleManager`, handling of unexpected contributor states after attach failure will be addressed in issue #47.
LanguageTool
CONTRIBUTING.md

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Additional comments not posted (5)
Sources/AblyChat/RoomLifecycleManager.swift (2)

168-222: Possible Unhandled Errors During Detach Operation

In the performDetachOperation method, errors from detaching contributors are accumulated, but the loop continues without handling non-fatal errors immediately. This could lead to multiple errors being thrown, potentially obscuring the root cause.

Consider collecting all errors and providing a comprehensive summary after attempting to detach all contributors. Alternatively, handle critical errors promptly if they should halt the detachment process.


246-269: Potential Infinite Loop Without Cancellation Handling

In the performReleaseOperation method, the detachLoop continues indefinitely until the contributor is successfully detached. If the task is cancelled, this loop may prevent the task from terminating properly, potentially leading to resource leaks or unresponsive behavior.

Consider adding a check for task cancellation within the loop to handle cancellations gracefully:

 detachLoop: while true {
     let contributorState = await contributor.channel.state

     // CHA-RL3e
     guard contributorState != .failed else {
         logger.log(message: "Contributor \(contributor) is FAILED; skipping detach", level: .info)
         break
     }

     logger.log(message: "Detaching contributor \(contributor)", level: .info)
     do {
         try await contributor.channel.detach()
         break detachLoop
     } catch {
         // CHA-RL3f: Retry until detach succeeds, with a pause before each attempt
         logger.log(message: "Failed to detach contributor \(contributor), error \(error). Will retry in 1s.", level: .info)
+        if Task.isCancelled {
+            logger.log(message: "Task was cancelled during detach operation.", level: .info)
+            return
+        }
         // TODO: Make this not trap in the case where the Task is cancelled (as part of the broader https://github.com/ably-labs/ably-chat-swift/issues/29 for handling task cancellation)
         // TODO: what's the correct wait time? (https://github.com/ably/specification/pull/200#discussion_r1763822207)
         // swiftlint:disable:next force_try
         try! await clock.sleep(nanoseconds: 1_000_000_000)
         // Loop repeats
     }
 }

Since this change relates to handling task cancellations, verify that the cancellation behavior aligns with the expected operation. Ensure that the task responds appropriately when cancellation is requested.

CONTRIBUTING.md (3)

31-45: Comprehensive Guidelines for Test Attribution

The added section provides clear and detailed instructions on how to attribute tests to spec points using the @spec, @specOneOf, and @specPartial tags. This will greatly improve test coverage traceability and ensure alignment with the Chat SDK features spec. The inclusion of examples further enhances understanding for contributors.

Tools
LanguageTool

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)


47-66: Effective Use of Examples to Illustrate Guidelines

The provided examples effectively demonstrate how to use the attribution tags in practice. They cover various scenarios, including single tests covering a spec point, multiple tests collaborating to cover a spec point, and partial test coverage. This clarity will aid developers in correctly applying the guidelines.


67-68: Proactive Planning for Coverage Reporting

Mentioning issue #46 to write a script for generating coverage reports shows foresight and a commitment to maintainability. This will help in assessing the implementation progress against the feature spec.

Comments failed to post (4)
Sources/AblyChat/Errors.swift (4)

164-175: Missing return Statements in cause Computed Property

The cause computed property requires return statements in each case of the switch statement to return the appropriate ARTErrorInfo? value. The current implementation lacks return keywords, leading to a compilation error.

Apply this diff to correct the implementation:

 internal var cause: ARTErrorInfo? {
     switch self {
     case let .attachmentFailed(_, underlyingError):
-        underlyingError
+        return underlyingError
     case let .detachmentFailed(_, underlyingError):
-        underlyingError
+        return underlyingError
     case .inconsistentRoomOptions,
          .roomInFailedState,
          .roomIsReleasing,
          .roomIsReleased:
-        nil
+        return nil
     }
 }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    /// The ``ARTErrorInfo.cause`` that should be returned for this error.
    internal var cause: ARTErrorInfo? {
        switch self {
        case let .attachmentFailed(_, underlyingError):
            return underlyingError
        case let .detachmentFailed(_, underlyingError):
            return underlyingError
        case .inconsistentRoomOptions,
             .roomInFailedState,
             .roomIsReleasing,
             .roomIsReleased:
            return nil

37-56: Missing return Statements in statusCode Computed Property

In the statusCode computed property, each case in the switch statement should explicitly return a value. The return keyword is currently missing before the status codes 400 and 500, which will lead to a compilation error.

Apply this diff to add the missing return statements:

 internal var statusCode: Int {
     // TODO: These are currently a guess, revisit once outstanding spec question re status codes is answered (https://github.com/ably/specification/pull/200#discussion_r1755222945), and also revisit in https://github.com/ably-labs/ably-chat-swift/issues/32
     switch self {
     case .inconsistentRoomOptions,
          .messagesDetachmentFailed,
          .presenceDetachmentFailed,
          .reactionsDetachmentFailed,
          .occupancyDetachmentFailed,
          .typingDetachmentFailed,
          .roomInFailedState,
          .roomIsReleasing,
          .roomIsReleased:
-        400
+        return 400
     case .messagesAttachmentFailed,
          .presenceAttachmentFailed,
          .reactionsAttachmentFailed,
          .occupancyAttachmentFailed,
          .typingAttachmentFailed:
         // TODO: This is currently a best guess based on the limited status code information given in the spec at time of writing (i.e. CHA-RL1h4); it's not clear to me whether these error codes are always meant to have the same status code. Revisit once aforementioned spec question re status codes answered.
-        500
+        return 500
     }
 }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        // TODO: These are currently a guess, revisit once outstanding spec question re status codes is answered (https://github.com/ably/specification/pull/200#discussion_r1755222945), and also revisit in https://github.com/ably-labs/ably-chat-swift/issues/32
        switch self {
        case .inconsistentRoomOptions,
             .messagesDetachmentFailed,
             .presenceDetachmentFailed,
             .reactionsDetachmentFailed,
             .occupancyDetachmentFailed,
             .typingDetachmentFailed,
             .roomInFailedState,
             .roomIsReleasing,
             .roomIsReleased:
            return 400
        case .messagesAttachmentFailed,
             .presenceAttachmentFailed,
             .reactionsAttachmentFailed,
             .occupancyAttachmentFailed,
             .typingAttachmentFailed:
            // TODO: This is currently a best guess based on the limited status code information given in the spec at time of writing (i.e. CHA-RL1h4); it's not clear to me whether these error codes are always meant to have the same status code. Revisit once aforementioned spec question re status codes answered.
            return 500
        }

145-162: Missing return Statements in localizedDescription Computed Property

In the localizedDescription computed property, each case in the switch statement should include a return statement to return the corresponding description string. The absence of return keywords will result in a compilation error.

Apply this diff to add the missing return statements:

 internal var localizedDescription: String {
     switch self {
     case let .inconsistentRoomOptions(requested, existing):
-        "Rooms.get(roomID:options:) was called with a different set of room options than was used on a previous call. You must first release the existing room instance using Rooms.release(roomID:). Requested options: \(requested), existing options: \(existing)"
+        return "Rooms.get(roomID:options:) was called with a different set of room options than was used on a previous call. You must first release the existing room instance using Rooms.release(roomID:). Requested options: \(requested), existing options: \(existing)"
     case let .attachmentFailed(feature, _):
         return Self.localizedDescription(forFailureOfOperation: .attach, feature: feature)
     case let .detachmentFailed(feature, _):
         return Self.localizedDescription(forFailureOfOperation: .detach, feature: feature)
     case .roomInFailedState:
-        "Cannot perform operation because the room is in a failed state."
+        return "Cannot perform operation because the room is in a failed state."
     case .roomIsReleasing:
-        "Cannot perform operation because the room is in a releasing state."
+        return "Cannot perform operation because the room is in a releasing state."
     case .roomIsReleased:
-        "Cannot perform operation because the room is in a released state."
+        return "Cannot perform operation because the room is in a released state."
     }
 }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    /// The ``ARTErrorInfo.localizedDescription`` that should be returned for this error.
    internal var localizedDescription: String {
        switch self {
        case let .inconsistentRoomOptions(requested, existing):
            return "Rooms.get(roomID:options:) was called with a different set of room options than was used on a previous call. You must first release the existing room instance using Rooms.release(roomID:). Requested options: \(requested), existing options: \(existing)"
        case let .attachmentFailed(feature, _):
            return Self.localizedDescription(forFailureOfOperation: .attach, feature: feature)
        case let .detachmentFailed(feature, _):
            return Self.localizedDescription(forFailureOfOperation: .detach, feature: feature)
        case .roomInFailedState:
            return "Cannot perform operation because the room is in a failed state."
        case .roomIsReleasing:
            return "Cannot perform operation because the room is in a releasing state."
        case .roomIsReleased:
            return "Cannot perform operation because the room is in a released state."
        }
    }

75-111: Missing return Statements in code Computed Property

The code computed property in the ChatError enum requires explicit return statements in each case of the switch statement. Currently, the return keyword is missing, which will cause a compilation error.

Apply this diff to add the missing return statements:

 internal var code: ErrorCode {
     switch self {
     case .inconsistentRoomOptions:
-        .inconsistentRoomOptions
+        return .inconsistentRoomOptions
     case let .attachmentFailed(feature, _):
         switch feature {
         case .messages:
-            .messagesAttachmentFailed
+            return .messagesAttachmentFailed
         case .occupancy:
-            .occupancyAttachmentFailed
+            return .occupancyAttachmentFailed
         case .presence:
-            .presenceAttachmentFailed
+            return .presenceAttachmentFailed
         case .reactions:
-            .reactionsAttachmentFailed
+            return .reactionsAttachmentFailed
         case .typing:
-            .typingAttachmentFailed
+            return .typingAttachmentFailed
         }
     case let .detachmentFailed(feature, _):
         switch feature {
         case .messages:
-            .messagesDetachmentFailed
+            return .messagesDetachmentFailed
         case .occupancy:
-            .occupancyDetachmentFailed
+            return .occupancyDetachmentFailed
         case .presence:
-            .presenceDetachmentFailed
+            return .presenceDetachmentFailed
         case .reactions:
-            .reactionsDetachmentFailed
+            return .reactionsDetachmentFailed
         case .typing:
-            .typingDetachmentFailed
+            return .typingDetachmentFailed
         }
     case .roomInFailedState:
-        .roomInFailedState
+        return .roomInFailedState
     case .roomIsReleasing:
-        .roomIsReleasing
+        return .roomIsReleasing
     case .roomIsReleased:
-        .roomIsReleased
+        return .roomIsReleased
     }
 }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        switch self {
        case .inconsistentRoomOptions:
            return .inconsistentRoomOptions
        case let .attachmentFailed(feature, _):
            switch feature {
            case .messages:
                return .messagesAttachmentFailed
            case .occupancy:
                return .occupancyAttachmentFailed
            case .presence:
                return .presenceAttachmentFailed
            case .reactions:
                return .reactionsAttachmentFailed
            case .typing:
                return .typingAttachmentFailed
            }
        case let .detachmentFailed(feature, _):
            switch feature {
            case .messages:
                return .messagesDetachmentFailed
            case .occupancy:
                return .occupancyDetachmentFailed
            case .presence:
                return .presenceDetachmentFailed
            case .reactions:
                return .reactionsDetachmentFailed
            case .typing:
                return .typingDetachmentFailed
            }
        case .roomInFailedState:
            return .roomInFailedState
        case .roomIsReleasing:
            return .roomIsReleasing
        case .roomIsReleased:
            return .roomIsReleased
        }
    }

@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch from e940d8b to df9ab14 Compare September 19, 2024 11:54
Copy link

@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: 0

Outside diff range and nitpick comments (2)
Sources/AblyChat/Errors.swift (2)

37-55: Status codes look good for detachment failures and room state errors, but reconsider for attachment failures.

  • Using 400 for detachment failures and room state errors seems appropriate as they likely indicate client errors.
  • For attachment failures, consider using 4xx status codes if the failure is due to client error. 500 should be reserved for server-side issues.

187-190: Good update to populate the cause property from chatError.cause.

This enhances error reporting by providing the underlying error.

Please follow up on the TODO comment to consider documenting the usage of NSUnderlyingErrorKey to populate cause in ably-cocoa.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b27744c and df9ab14.

Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
Files skipped from review as they are similar to previous changes (6)
  • Sources/AblyChat/RoomFeature.swift
  • Sources/AblyChat/SimpleClock.swift
  • Tests/AblyChatTests/Helpers/Helpers.swift
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift
Additional context used
Learnings (1)
Sources/AblyChat/RoomLifecycleManager.swift (4)
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:265-266
Timestamp: 2024-09-18T18:29:10.329Z
Learning: In `RoomLifecycleManager.swift`, the use of `try!` with `await` for `clock.sleep` is intentional due to reasons outlined in the associated GitHub issue. Do not suggest changing this usage unless the issue is resolved.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:262-262
Timestamp: 2024-09-18T18:29:03.379Z
Learning: When a TODO comment references an associated GitHub issue, recognize that the issue is being tracked and avoid suggesting fixes that are already planned.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#9
File: Sources/AblyChat/RoomStatus.swift:3-33
Timestamp: 2024-08-28T13:01:11.701Z
Learning: When reviewing code, avoid commenting on TODOs that already have a linked GitHub issue, as per the user's preference.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:0-0
Timestamp: 2024-09-18T18:34:37.252Z
Learning: In `RoomLifecycleManager`, handling of unexpected contributor states after attach failure will be addressed in issue #49.
LanguageTool
CONTRIBUTING.md

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Additional comments not posted (11)
CONTRIBUTING.md (1)

31-73: Excellent addition of testing guidelines!

The new testing guidelines introduce a structured approach to attributing tests to spec points using the @spec, @specOneOf, @specPartial, and @specUntested tags. This enhances the clarity and organization of the test suite, making it easier to track test coverage and identify gaps in the implementation of the feature spec.

The code examples provided are clear and demonstrate the usage of the tags effectively. The requirement for an explanation when using the @specUntested tag ensures that the absence of tests is justified, promoting a disciplined approach to testing.

These changes will greatly improve the maintainability and documentation of the test suite, ensuring that tests are well-aligned with the specifications.

Tools
LanguageTool

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Sources/AblyChat/Errors.swift (4)

19-23: Excellent addition of granular error codes for attachment failures!

The new error codes provide a clean way to distinguish attachment failures for different room features. The chosen naming convention and error code range are very appropriate.


25-29: Great job adding granular error codes for detachment failures!

The new error codes provide a clean way to distinguish detachment failures for different room features. The naming convention is consistent with the attachment failure codes, and the chosen error code range provides a clear separation.


31-33: Nice addition of error codes for room state errors!

The new error codes cover critical room states that could lead to errors. The naming is clear, and the error code range is distinct from other error categories.


67-175: Excellent enhancements to the ChatError enum for better error handling and reporting!

  • The new attachmentFailed and detachmentFailed cases, along with the associated code, localizedDescription, and cause properties, significantly improve the error handling and reporting capabilities.
  • Mapping the ChatError cases to appropriate ErrorCode values in the code property is spot on.
  • The localizedDescription property, with the help of the new helper method, constructs very clear and contextual error messages.
  • Returning the underlying error in the cause property for attachment and detachment failures is a great addition for better error reporting.
Sources/AblyChat/RoomLifecycleManager.swift (6)

3-15: Async methods and state in RoomLifecycleContributorChannel protocol

The use of async methods for attach and detach instead of callbacks is a good design choice. It makes it easier to create mocks for testing, as the type system can ensure that the callbacks are Sendable.

Marking the channel's mutable state as async is a clever way to highlight the possibility of concurrent modifications from a separate thread. While it doesn't solve concurrency issues, it makes them more visible to the caller.

The TODO comment indicates that the resolution of these concurrency issues will be tracked in a separate issue, which is a good approach.


17-274: RoomLifecycleManager actor design

The use of an actor for encapsulating the lifecycle management logic and state is a good design choice. It ensures thread safety and consistency by protecting the internal state and providing a clear interface for interacting with the lifecycle manager.

The generic Channel type parameter constrained to the RoomLifecycleContributorChannel protocol allows for flexibility and testability. It enables the use of different channel implementations, including mocks for testing purposes.

Marking the current and error properties as internal private(set) is a good practice. It ensures that these properties can only be modified within the actor, maintaining the integrity of the lifecycle state.

The onChange method provides a convenient way for subscribers to react to room status changes. This is useful for updating the UI or performing other actions based on lifecycle events.

The changeStatus and emitStatusChange methods encapsulate the logic for updating the current state and notifying subscribers. This promotes code reuse and maintainability by centralizing the state management logic.

Overall, the RoomLifecycleManager actor is well-designed and follows good practices for managing the lifecycle of real-time chat room contributors.


19-24: Contributor struct design

The Contributor struct provides a clean and concise way to encapsulate the contributor's feature and channel. It keeps the related data together and makes it easy to pass around the contributor information.

The feature property is a nice touch for providing context when throwing errors related to contributor operations. It allows for more specific error messages that indicate which feature encountered an issue.

The channel property's type is constrained by the generic type parameter of the RoomLifecycleManager actor. This ensures that the channel conforms to the RoomLifecycleContributorChannel protocol, providing a consistent interface for interacting with the contributor's channel.

Overall, the Contributor struct is a well-designed and purposeful addition to the RoomLifecycleManager actor.


71-130: performAttachOperation method implementation

The performAttachOperation method closely follows the CHA-RL1 specification for the ATTACH operation. It correctly implements the required state transitions and error handling based on the current state and the result of attaching the contributors.

The use of a switch statement to handle different current states is a clear and concise way to implement the state-based behavior. It makes the code readable and easy to understand.

The method includes informative logging messages at key points, such as when attaching a contributor or handling a failed attachment. These messages are helpful for debugging and understanding the lifecycle flow.

The error handling for failed contributor attachments is comprehensive and follows the specification rules. It takes into account the contributor's state and throws the appropriate errors based on the specification.

The TODO comment indicates that the asynchronous part of CHA-RL1h5 needs to be implemented, and it is tracked in a separate issue. This is a good practice for keeping the code maintainable and ensuring that the remaining work is not forgotten.

Overall, the performAttachOperation method is well-implemented and adheres to the CHA-RL1 specification.


149-226: performDetachOperation method implementation

The performDetachOperation method closely follows the CHA-RL2 specification for the DETACH operation. It correctly implements the required state transitions and error handling based on the current state and the result of detaching the contributors.

The use of a switch statement to handle different current states is a clear and concise way to implement the state-based behavior. It makes the code readable and easy to understand.

The method includes informative logging messages at key points, such as when detaching a contributor or handling a failed detachment. These messages are helpful for debugging and understanding the lifecycle flow.

The error handling for failed contributor detachments is comprehensive and follows the specification rules. It takes into account the contributor's state and handles the errors accordingly, such as storing the first detach error to be thrown later and transitioning to the failed state if necessary.

The retry logic for non-failed contributors is implemented as per the specification, with a pause between each attempt. This ensures that the detachment is retried until it succeeds, as required by the specification.

The TODO comment indicates that the correct wait time for the retry pause needs to be determined, and it is tracked in a separate discussion. This is a good practice for keeping the code maintainable and ensuring that the remaining work is not forgotten.

Overall, the performDetachOperation method is well-implemented and adheres to the CHA-RL2 specification.


228-273: performReleaseOperation method implementation

The performReleaseOperation method closely follows the CHA-RL3 specification for the RELEASE operation. It correctly implements the required state transitions and contributor detachment logic based on the current state.

The use of a switch statement to handle different current states is a clear and concise way to implement the state-based behavior. It makes the code readable and easy to understand.

The method includes informative logging messages at key points, such as when skipping a failed contributor or retrying a detachment. These messages are

Copy link
Collaborator

@maratal maratal left a comment

Choose a reason for hiding this comment

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

Left some questions.

CONTRIBUTING.md Show resolved Hide resolved
Sources/AblyChat/RoomLifecycleManager.swift Show resolved Hide resolved
Sources/AblyChat/SimpleClock.swift Outdated Show resolved Hide resolved
@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch from df9ab14 to 84711d5 Compare September 19, 2024 15:58
@lawrence-forooghian lawrence-forooghian changed the base branch from main to fix-swiftlint-version September 19, 2024 15:58
Base automatically changed from fix-swiftlint-version to main September 19, 2024 17:04
@lawrence-forooghian
Copy link
Collaborator Author

Will address conflicts and switch to Swift Testing now that #61 is merged.

@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch from 84711d5 to 30cd397 Compare September 23, 2024 14:18
Copy link

@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: 0

Outside diff range and nitpick comments (5)
CONTRIBUTING.md (1)

45-67: LGTM: Comprehensive examples and future plans

The additional details and examples effectively illustrate the proper use of each tag. The mention of the future script (issue #46) provides valuable context for the purpose of these tags in generating reports on spec implementation coverage.

Suggestion: Consider adding a brief note about the importance of keeping these tags up-to-date as the codebase evolves, to ensure the accuracy of the generated reports.

Sources/AblyChat/Errors.swift (4)

19-33: LGTM! Consider adding comments for new error codes.

The new error codes for attachment/detachment failures and room state errors are well-organized and align with the PR objectives. They follow a consistent naming convention and numbering scheme.

Consider adding brief comments for each new error code to explain their purpose, similar to the existing comment for inconsistentRoomOptions. This would improve code documentation and make it easier for other developers to understand the purpose of each error code.


37-55: LGTM! Consider tracking the TODO comment.

The statusCode property has been updated correctly to include the new error cases. The assignment of HTTP status codes (400 and 500) for different error types is logical.

The TODO comment indicates that the status codes are currently a best guess and may need revision once the specification question is answered. To ensure this is not overlooked, would you like me to create a GitHub issue to track this TODO and link it to the specification question (ably/specification#200 (comment))?


114-162: LGTM! Consider using string interpolation for better readability.

The new helper method localizedDescription(forFailureOfOperation:feature:) and the updated localizedDescription property greatly improve the error message generation. The implementation is clean, reusable, and follows Swift best practices.

Consider using string interpolation for the error messages in the localizedDescription property to improve readability. For example:

case .roomInFailedState:
    "Cannot perform operation because the room is in a failed state."

Could be written as:

case .roomInFailedState:
    "Cannot perform operation because the room is in a \(self) state."

This would make it easier to maintain consistent wording across similar error messages.


Line range hint 165-190: LGTM! Consider tracking the TODO comment about documentation.

The new cause property in ChatError and its integration into the ARTErrorInfo extension are well-implemented. This change improves error reporting by including underlying error information for attachment and detachment failures.

The TODO comment suggests documenting the use of NSUnderlyingErrorKey in ably-cocoa. To ensure this documentation task is not overlooked, would you like me to create a GitHub issue to track this TODO and link it to the mentioned issue (#32)?

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between df9ab14 and 30cd397.

Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
Files skipped from review as they are similar to previous changes (7)
  • Sources/AblyChat/RoomFeature.swift
  • Sources/AblyChat/RoomLifecycleManager.swift
  • Sources/AblyChat/SimpleClock.swift
  • Tests/AblyChatTests/Helpers/Helpers.swift
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift
Additional context used
LanguageTool
CONTRIBUTING.md

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Additional comments not posted (7)
CONTRIBUTING.md (5)

31-32: LGTM: Clear guideline for spec referencing

This addition provides a clear instruction for developers to link code implementations with the Chat SDK features spec. This practice enhances traceability and helps maintain alignment between the code and the specification.


33-41: LGTM: Comprehensive test attribution guidelines

The new testing guidelines provide a clear and structured approach for attributing tests to specific spec points. The three tags (@spec, @specOneOf, and @specPartial) are well-defined and offer flexibility in describing the relationship between tests and spec items.

Note: The use of "different to" in line 41 is correct as it adheres to British English conventions, which this project follows.

Tools
LanguageTool

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


42-43: LGTM: Improved clarity in spec-item-id explanation

The explanation of the <spec-item-id> parameter has been rephrased to form a complete sentence, improving clarity. This change addresses the previous suggestion and enhances the overall readability of the guidelines.

Tools
LanguageTool

[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)


69-73: LGTM: Valuable addition of @specUntested tag

The introduction of the @specUntested tag is a valuable addition to the testing guidelines. It provides a way to document implemented spec points that lack automated tests, promoting transparency in test coverage. The requirement for an explanation ensures that the use of this tag is justified and well-documented.

Note: The previously identified typographical error has been corrected ("an explanation" is now used correctly).


31-73: Overall: Excellent enhancement to testing guidelines

These changes to the CONTRIBUTING.md file introduce a robust and well-structured system for attributing tests to spec points. The new guidelines will significantly improve traceability between the codebase and the Chat SDK features specification, enhancing the overall quality and maintainability of the project.

Key improvements:

  1. Clear instructions for referencing spec items in code
  2. Comprehensive test attribution tags (@spec, @specOneOf, @specPartial, @specUntested)
  3. Detailed examples illustrating proper tag usage
  4. Transparency in documenting untested spec points

These additions will greatly assist developers in maintaining alignment between the codebase and the specification, as well as facilitate future automation for tracking spec implementation coverage.

Tools
LanguageTool

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Sources/AblyChat/Errors.swift (2)

67-110: LGTM! ChatError enum updated correctly.

The ChatError enum has been expanded to include new cases for attachment/detachment failures and room state errors. The code property has been updated to handle these new cases, correctly mapping them to their corresponding ErrorCode values. These changes align well with the PR objectives and maintain consistency with the existing implementation.


Line range hint 1-197: Overall, excellent implementation of error handling enhancements.

The changes in this file significantly improve the error handling capabilities of the AblyChat SDK, aligning well with the PR objectives for implementing the room lifecycle spec. The new error codes, ChatError cases, and supporting methods are well-organized and consistently implemented. The enhancements to error reporting, including the addition of the cause property and its integration with ARTErrorInfo, will greatly assist in debugging and error resolution.

A few minor suggestions have been made to further improve documentation and maintainability. Consider addressing the TODO comments by creating tracking issues to ensure these points are not overlooked in future development.

Great work on enhancing the error handling system!

@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch from 30cd397 to 4c9eb86 Compare September 23, 2024 19:26
Copy link

@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: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 30cd397 and 4c9eb86.

Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
Files skipped from review as they are similar to previous changes (8)
  • Sources/AblyChat/Errors.swift
  • Sources/AblyChat/RoomFeature.swift
  • Sources/AblyChat/RoomLifecycleManager.swift
  • Sources/AblyChat/SimpleClock.swift
  • Tests/AblyChatTests/Helpers/Helpers.swift
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift
Additional context used
LanguageTool
CONTRIBUTING.md

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Additional comments not posted (2)
CONTRIBUTING.md (2)

31-32: Excellent addition for maintaining spec traceability

This guideline ensures that developers explicitly link code implementations to the Chat SDK features specification. This practice will greatly enhance code maintainability and help in future audits or updates to the specification.


31-73: Excellent enhancements to contribution guidelines

The additions to the CONTRIBUTING.md file significantly improve the project's documentation and testing practices. These changes:

  1. Establish clear guidelines for referencing spec items in code implementation.
  2. Introduce a comprehensive system for attributing tests to spec points, enhancing traceability.
  3. Provide a mechanism for documenting implemented but untested spec points.

These enhancements align perfectly with the PR objectives, particularly in implementing and tracking the room lifecycle specification. They will greatly facilitate the development process, improve code maintainability, and ensure comprehensive coverage of the Chat SDK features specification.

Great job on these additions! They will undoubtedly have a positive impact on the project's development and maintenance processes.

Tools
LanguageTool

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

CONTRIBUTING.md Show resolved Hide resolved
CONTRIBUTING.md Outdated Show resolved Hide resolved
@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch from 4c9eb86 to c70ee44 Compare September 23, 2024 19:38
@lawrence-forooghian
Copy link
Collaborator Author

Will address conflicts and switch to Swift Testing now that #61 is merged.

Done.

Copy link

@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: 26

Outside diff range and nitpick comments (1)
CONTRIBUTING.md (1)

31-67: LGTM! Clear and comprehensive test attribution guidelines.

The new section on attributing tests to spec points is well-structured and provides clear guidance for developers. The three types of tags (@SPEC, @specOneOf, and @specPartial) offer flexibility in describing test coverage, and the examples are particularly helpful for understanding the usage of each tag.

One minor suggestion for improvement:
Consider adding a brief explanation of why attributing tests to spec points is important at the beginning of the section. This could help motivate developers to follow these guidelines consistently.

You could add a brief introductory sentence like:

 ### Testing guidelines
 
+Attributing tests to spec points helps maintain traceability between the implementation and the specification, ensuring comprehensive test coverage and facilitating future updates or audits of the SDK.
+
 #### Attributing tests to a spec point
Tools
LanguageTool

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4c9eb86 and c70ee44.

Files selected for processing (9)
  • CONTRIBUTING.md (1 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
Files skipped from review as they are similar to previous changes (7)
  • Sources/AblyChat/Errors.swift
  • Sources/AblyChat/RoomFeature.swift
  • Sources/AblyChat/RoomLifecycleManager.swift
  • Sources/AblyChat/SimpleClock.swift
  • Tests/AblyChatTests/Helpers/Helpers.swift
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift
Additional context used
LanguageTool
CONTRIBUTING.md

[grammar] ~41-~41: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~43-~43: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

Additional comments not posted (2)
CONTRIBUTING.md (2)

69-73: LGTM! Clear guidelines for marking untested spec points.

The introduction of the @specUntested tag is a valuable addition to the testing guidelines. It provides a way to acknowledge implemented spec points that cannot be automatically tested, ensuring comprehensive tracking of the specification implementation. The emphasis on sparing use and the requirement for an explanation are appropriate safeguards against overuse.


75-79: LGTM! Excellent example of @specUntested usage.

The provided example effectively demonstrates the proper use of the @specUntested tag. The explanation is thorough and clearly justifies why the spec point cannot be tested automatically. This example will be valuable for developers in understanding when and how to use this tag appropriately.

Copy link
Collaborator

@maratal maratal left a comment

Choose a reason for hiding this comment

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

LGTM

@lawrence-forooghian lawrence-forooghian changed the base branch from main to convention-for-test-only-apis September 30, 2024 16:03
@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch 3 times, most recently from 50d1ee0 to a4d3c52 Compare September 30, 2024 16:56
Copy link

@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: 0

🧹 Outside diff range and nitpick comments (4)
Tests/AblyChatTests/RoomLifecycleManagerTests.swift (4)

157-159: Offer assistance on unresolved TODO

There's a TODO comment indicating an outstanding question regarding the meaning of CHA-RL1h1 in the specification. If you'd like, I can help clarify this point or assist in drafting queries to resolve the issue.


251-251: Offer assistance on implementing pending behavior

You've noted a need to implement the behavior for CHA-RL1h5 as a separate piece of work. I'd be happy to assist in implementing this functionality or help create a GitHub issue to track it. Let me know if you'd like help with this.


478-478: Assist with testing untested spec point

You've mentioned difficulty in testing spec point CHA-RL2h2 due to concurrency limitations. I can help explore alternative testing strategies or assist in opening a GitHub issue to gather insights from others. Please let me know if you'd like assistance.


653-653: Assist with TODO on spec interpretation

There's a TODO comment about confirming the interpretation of CHA-RL3f, particularly regarding whether the wait occurs without a retry. I can help review the specification and confirm this behavior, or assist in drafting a query to the team for clarification.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c70ee44 and a4d3c52.

📒 Files selected for processing (9)
  • CONTRIBUTING.md (2 hunks)
  • Sources/AblyChat/Errors.swift (2 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomLifecycleManager.swift (1 hunks)
  • Sources/AblyChat/SimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/Helpers/Helpers.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift (1 hunks)
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift (1 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • Sources/AblyChat/Errors.swift
  • Sources/AblyChat/RoomFeature.swift
  • Sources/AblyChat/RoomLifecycleManager.swift
  • Sources/AblyChat/SimpleClock.swift
  • Tests/AblyChatTests/Helpers/Helpers.swift
  • Tests/AblyChatTests/Mocks/MockRoomLifecycleContributorChannel.swift
  • Tests/AblyChatTests/Mocks/MockSimpleClock.swift
🧰 Additional context used
📓 Learnings (1)
Tests/AblyChatTests/RoomLifecycleManagerTests.swift (1)
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:335-335
Timestamp: 2024-09-23T19:56:39.435Z
Learning: In Swift Testing, test method names do not need to start with `test`.
🪛 LanguageTool
CONTRIBUTING.md

[grammar] ~62-~62: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~64-~64: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)

🔇 Additional comments (6)
CONTRIBUTING.md (4)

31-31: Excellent addition for code-spec traceability

This guideline is a great practice for maintaining clear links between the implementation and the specification. It will significantly aid in code review and future maintenance.

To further enhance clarity, consider providing a brief example of how to format such a comment. For instance:

// Implements CHA-EX1a: Initializes the chat room with the given parameters
func initializeChatRoom(name: String, participants: [User]) {
    // Implementation details...
}

56-88: Comprehensive test attribution guidelines

The new section on attributing tests to spec points is well-structured and provides clear guidance for developers. The three types of tags (@SPEC, @specOneOf, and @specPartial) offer flexibility in describing test coverage. The examples are particularly helpful for understanding the usage of each tag.

To further enhance this section, consider adding a brief note about the importance of consistent tag usage across the test suite. For example:

 In [#46](https://github.com/ably-labs/ably-chat-swift/issues/46), we'll write a script that uses these tags to generate a report about how much of the feature spec we've implemented.
+
+Consistent use of these tags across the test suite is crucial for accurate reporting and maintaining a clear overview of our test coverage relative to the specification.
🧰 Tools
🪛 LanguageTool

[grammar] ~62-~62: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)


[uncategorized] ~64-~64: Possible missing comma found.
Context: ...em-id>parameter should be a spec item identifier such asCHA-RL3g`. Each of the above ...

(AI_HYDRA_LEO_MISSING_COMMA)


90-100: Valuable addition for tracking untested spec points

The introduction of the @specUntested tag is a great way to maintain transparency about test coverage. It provides a structured way to acknowledge implemented spec points that cannot be automatically tested, ensuring comprehensive tracking of the specification implementation.

To further strengthen this practice, consider adding a guideline to periodically review @specUntested items. For example:

 // @specUntested CHA-EX2b - I was unable to find a way to test this spec point in an environment in which concurrency is being used; there is no obvious moment at which to stop observing the emitted state changes in order to be sure that FAILED has not been emitted twice.

+It's recommended to periodically review @specUntested items to determine if new testing strategies or tools have become available that might allow for automated testing of these spec points.


---

`62-62`: **Correct usage of "different to" in British English**

The phrase "different to" in this line is correct according to British English conventions, which this project follows.

To prevent future false positives from static analysis tools, consider adding a comment to explicitly indicate the use of British English. For example:

```diff
- This is different to `@specOneOf` in that it implies that the test suite does not fully test this spec item.
+ This is different to `@specOneOf` in that it implies that the test suite does not fully test this spec item. // Using British English convention

This comment will help other contributors understand the intentional use of British English and can be used to configure language-specific linting rules if needed in the future.

🧰 Tools
🪛 LanguageTool

[grammar] ~62-~62: In American English, the usual prepositions after ‘different’ are “from” or “than”.
Context: ...ted in the spec item. This is different to @specOneOf in that it implies that th...

(DIFFERENT_TO)

Tests/AblyChatTests/RoomLifecycleManagerTests.swift (2)

30-36: Helper function createManager is well-structured

The createManager helper function is clearly defined and provides flexibility in setting up the RoomLifecycleManager for different test scenarios.


38-45: Helper function createContributor enhances test flexibility

The createContributor function allows for efficient creation of contributors with customizable initial states and behaviors, which is excellent for testing various conditions.

This is based on [1] at b4a495e. It’s generated some questions, which
I’ve asked on that PR.

Note that the spec has been through a few revisions since I started
implementing this; I’ve tried to keep everything in sync but some older
stuff might still be accidentally there.

I’ve implemented most of the specified behaviour for the ATTACH, DETACH,
and RELEASE operations. I have not yet implemented RETRY since it’s
quite different to those three and I wanted to get eyes on this first
chunk of work; have created #51 for implementing it.

Of the operations that I have implemented, I have not implemented the
following (this is accurately reflected by the @SPEC… tags in the
tests):

- Lifecycle behaviour that relates to another ongoing operation (created
  #52)

- Lifecycle behaviour relating to “transient disconnect timeouts”
  (created #48)

- Lifecycle behaviour that occurs “asynchronously” outside an operation
  (created #50)

- CHA-RL1g2, which refers to emitting “discontinuity events” which are a
  concept not yet implemented; this will come in #53.

The room lifecycle manager introduced by this commit is currently a
standalone object, which is not integrated with the rest of the SDK.
I’ve created #47 for doing this integration work.

The @SPEC… tags are based on the on the JS rules [2] @ 8c9ce8b, but I
camel-cased them and also decided that:

- if a test doesn't relate to a spec point, it doesn't need any markers

- there should be a way to know that a spec point is tested across
  multiple tests

- there should be a way of marking a spec point as implemented but not
  tested (so that can show up differently in reporting; important given
  that we’re also going to use this report as a to-do list of what still
  needs to be implemented)

Part of #28.

[1] ably/specification#200
[2] https://github.com/ably/ably-js/blob/main/CONTRIBUTING.md#tests-alignment-with-the-ably-features-specification
@lawrence-forooghian lawrence-forooghian force-pushed the 28-start-implementing-room-lifecycle-spec branch from a4d3c52 to 608f43e Compare September 30, 2024 17:14
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.

2 participants