Skip to content

Commit

Permalink
Added user emitting events for all mock subscriptions.
Browse files Browse the repository at this point in the history
  • Loading branch information
maratal committed Sep 9, 2024
1 parent 5bbb780 commit a82f177
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 57 deletions.
27 changes: 23 additions & 4 deletions Example/AblyChatExample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct ContentView: View {
.task {
for await reaction in await room().reactions.subscribe(bufferingPolicy: .unbounded) {
withAnimation {
reactions.append(reaction.type == "like" ? "👍" : "🤷")
reactions.append(reaction.displayedText)
}
}
}
Expand Down Expand Up @@ -111,9 +111,6 @@ struct ContentView: View {

func sendReaction(type: String) async throws {
try await room().reactions.send(params: .init(type: type))
withAnimation {
reactions.append("👍")
}
}
}

Expand Down Expand Up @@ -170,3 +167,25 @@ extension PresenceEventType {
}
}
}

extension Reaction {

static let values = ["like", "dislike", "lol", "rofl", "ok", "idk"]

var displayedText: String {
switch type {
case "like":
return "👍"
case "dislike":
return "👎"
case "lol":
return "😆"
case "rofl":
return "😂"
case "ok":
return "👌"
default:
return "🤷‍♀️"
}
}
}
6 changes: 4 additions & 2 deletions Example/AblyChatExample/Mocks/Misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ final class MockMessagesPaginatedResult: PaginatedResult {
Message(timeserial: "\(Date().timeIntervalSince1970)",
clientID: self.clientID,
roomID: self.roomID,
text: String.randomPhrase(),
text: MockStrings.randomPhrase(),
createdAt: Date(),
metadata: [:],
headers: [:])
Expand Down Expand Up @@ -65,7 +65,9 @@ final class MockPresencePaginatedResult: PaginatedResult {
var current: any PaginatedResult<T> { fatalError("Not implemented") }
}

extension String {
class MockStrings {

static let names = [ "Alice", "Bob", "Charlie", "Dave", "Eve" ]

static func randomWord(length: Int = Int.random(in: 1...10)) -> String {
var word = ""
Expand Down
127 changes: 90 additions & 37 deletions Example/AblyChatExample/Mocks/MockSubscriptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ struct MockMessageSubscription: Sendable, AsyncSequence {
func emitMessages() {
Task {
while (true) {
try? await Task.sleep(nanoseconds: 2 * 1_000_000_000)
_ = emit(message: SendMessageParams(text: String.randomPhrase()))
try? await Task.sleep(nanoseconds: 3 * 1_000_000_000)
_ = emit(message: SendMessageParams(text: MockStrings.randomPhrase()))
}
}
}
Expand All @@ -46,71 +46,124 @@ struct MockMessageSubscription: Sendable, AsyncSequence {
}
}

struct MockReactionSubscription: Sendable, AsyncSequence, AsyncIteratorProtocol {
struct MockReactionSubscription: Sendable, AsyncSequence {
typealias Element = Reaction
typealias AsyncIterator = AsyncStream<Element>.Iterator

let clientID: String
let roomID: String

public init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
private let stream: AsyncStream<Element>
private let continuation: AsyncStream<Element>.Continuation

func emit(reaction params: RoomReactionParams) {
let reaction = Reaction(type: params.type,
metadata: [:],
headers: [:],
createdAt: Date(),
clientID: self.clientID,
isSelf: false)
continuation.yield(reaction)
}

public mutating func next() async -> Element? {
try? await Task.sleep(nanoseconds: 1 * 1_000_000_000)
return Reaction(type: "like",
metadata: [:],
headers: [:],
createdAt: Date(),
clientID: self.clientID,
isSelf: false)
func emitReactions() {
Task {
while (true) {
try? await Task.sleep(nanoseconds: 1 * 1_000_000_000)
emit(reaction: RoomReactionParams(type: Reaction.values.randomElement()!))
}
}
}

public func makeAsyncIterator() -> Self {
self
func makeAsyncIterator() -> AsyncIterator {
stream.makeAsyncIterator()
}

init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
let (stream, continuation) = AsyncStream.makeStream(of: Element.self, bufferingPolicy: .unbounded)
self.stream = stream
self.continuation = continuation
emitReactions()
}
}

struct MockTypingSubscription: Sendable, AsyncSequence, AsyncIteratorProtocol {
struct MockTypingSubscription: Sendable, AsyncSequence {
typealias Element = TypingEvent
typealias AsyncIterator = AsyncStream<Element>.Iterator

let clientID: String
let roomID: String

public init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
private let stream: AsyncStream<Element>
private let continuation: AsyncStream<Element>.Continuation

func emit() {
let typing = TypingEvent(currentlyTyping: [MockStrings.names.randomElement()!, MockStrings.names.randomElement()!])
continuation.yield(typing)
}

func emitTypings() {
Task {
while (true) {
try? await Task.sleep(nanoseconds: 2 * 1_000_000_000)
emit()
}
}
}

public mutating func next() async -> Element? {
try? await Task.sleep(nanoseconds: 2 * 1_000_000_000)
return TypingEvent(currentlyTyping: ["User1", "User2"])
func makeAsyncIterator() -> AsyncIterator {
stream.makeAsyncIterator()
}

public func makeAsyncIterator() -> Self {
self
init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
let (stream, continuation) = AsyncStream.makeStream(of: Element.self, bufferingPolicy: .unbounded)
self.stream = stream
self.continuation = continuation
emitTypings()
}
}

struct MockPresenceSubscription: Sendable, AsyncSequence, AsyncIteratorProtocol {
struct MockPresenceSubscription: Sendable, AsyncSequence {
typealias Element = PresenceEvent
typealias AsyncIterator = AsyncStream<Element>.Iterator

private let members: [String]
let clientID: String
let roomID: String

init(members: [String]) {
self.members = members
private let stream: AsyncStream<Element>
private let continuation: AsyncStream<Element>.Continuation

func emitPresenceEvent() {
let presence = PresenceEvent(action: [.enter, .leave].randomElement()!,
clientID: MockStrings.names.randomElement()!,
timestamp: Date(),
data: nil)
continuation.yield(presence)
}

public mutating func next() async -> Element? {
try? await Task.sleep(nanoseconds: 4 * 1_000_000_000)
return PresenceEvent(action: [.enter, .leave].randomElement()!,
clientID: members.randomElement()!,
timestamp: Date(),
data: nil)
func emitPresenceEvents() {
Task {
while (true) {
try? await Task.sleep(nanoseconds: 5 * 1_000_000_000)
emitPresenceEvent()
}
}
}

public func makeAsyncIterator() -> Self {
self
func makeAsyncIterator() -> AsyncIterator {
stream.makeAsyncIterator()
}

init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
let (stream, continuation) = AsyncStream.makeStream(of: Element.self, bufferingPolicy: .unbounded)
self.stream = stream
self.continuation = continuation
emitPresenceEvents()
}
}
24 changes: 10 additions & 14 deletions Example/AblyChatExample/Mocks/Mocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,21 @@ actor MockRoomReactions: RoomReactions {
let roomID: String
let channel: RealtimeChannel

private var mockSubscription: MockReactionSubscription

init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
self.channel = MockRealtimeChannel()
self.mockSubscription = MockReactionSubscription(clientID: clientID, roomID: roomID)
}

func send(params: RoomReactionParams) async throws {
_ = Reaction(type: "like",
metadata: [:],
headers: [:],
createdAt: Date(),
clientID: clientID,
isSelf: true)
mockSubscription.emit(reaction: params)
}

func subscribe(bufferingPolicy: BufferingPolicy) -> Subscription<Reaction> {
.init(mockAsyncSequence: MockReactionSubscription(clientID: clientID, roomID: roomID))
.init(mockAsyncSequence: mockSubscription)
}

func subscribeToDiscontinuities() async -> Subscription<ARTErrorInfo> {
Expand All @@ -155,7 +153,7 @@ actor MockTyping: Typing {
}

func get() async throws -> Set<String> {
["User1", "User2"]
Set(MockStrings.names.prefix(2))
}

func start() async throws {
Expand All @@ -175,19 +173,17 @@ actor MockPresence: Presence {
let clientID: String
let roomID: String

private let members = [ "Alice", "Bob", "Charlie", "Dave", "Eve" ]

init(clientID: String, roomID: String) {
self.clientID = clientID
self.roomID = roomID
}

func get() async throws -> any PaginatedResult<PresenceMember> {
MockPresencePaginatedResult(members: members)
MockPresencePaginatedResult(members: MockStrings.names)
}

func get(params: ARTRealtimePresenceQuery?) async throws -> any PaginatedResult<PresenceMember> {
MockPresencePaginatedResult(members: members)
MockPresencePaginatedResult(members: MockStrings.names)
}

func isUserPresent(clientID: String) async throws -> Bool {
Expand Down Expand Up @@ -219,11 +215,11 @@ actor MockPresence: Presence {
}

func subscribe(event: PresenceEventType) -> Subscription<PresenceEvent> {
.init(mockAsyncSequence: MockPresenceSubscription(members: members))
.init(mockAsyncSequence: MockPresenceSubscription(clientID: clientID, roomID: roomID))
}

func subscribe(events: [PresenceEventType]) -> Subscription<PresenceEvent> {
.init(mockAsyncSequence: MockPresenceSubscription(members: members))
.init(mockAsyncSequence: MockPresenceSubscription(clientID: clientID, roomID: roomID))
}

func subscribeToDiscontinuities() async -> Subscription<ARTErrorInfo> {
Expand Down

0 comments on commit a82f177

Please sign in to comment.