Skip to content

Commit

Permalink
chore: kickoff release
Browse files Browse the repository at this point in the history
  • Loading branch information
ruisebas authored Apr 30, 2024
2 parents af4a5f7 + 6e2a881 commit bd6e02a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 113 deletions.
59 changes: 30 additions & 29 deletions .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ concurrency:
cancel-in-progress: ${{ github.ref_name != 'main'}}

jobs:
unit-tests-without-coverage:
targets-without-coverage:
name: ${{ matrix.scheme }} Unit Tests
strategy:
fail-fast: false
Expand All @@ -54,7 +54,7 @@ jobs:
scheme: ${{ matrix.scheme }}
generate_coverage_report: false

unit-tests-with-coverage:
targets-with-coverage:
name: ${{ matrix.scheme }} Unit Tests
strategy:
fail-fast: false
Expand All @@ -76,40 +76,41 @@ jobs:
uses: ./.github/workflows/run_unit_tests_platforms.yml
with:
scheme: ${{ matrix.scheme }}
generate_coverage_report: true
generate_coverage_report: ${{ vars.DISABLE_COVERAGE_REPORT != 'true' }}

# report-coverage:
# name: ${{ matrix.file.scheme }} Unit Tests
# needs: [unit-tests-with-coverage]
# strategy:
# fail-fast: false
# matrix:
# file: [
# { scheme: Amplify, flags: 'Amplify,unit_tests' },
# { scheme: AWSPluginsCore, flags: 'AWSPluginsCore,unit_tests' },
# { scheme: AWSAPIPlugin, flags: 'API_plugin_unit_test,unit_tests' },
# { scheme: AWSCloudWatchLoggingPlugin, flags: 'Logging_plugin_unit_test,unit_tests' },
# { scheme: AWSCognitoAuthPlugin, flags: 'Auth_plugin_unit_test,unit_tests' },
# { scheme: AWSDataStorePlugin, flags: 'DataStore_plugin_unit_test,unit_tests' },
# { scheme: AWSLocationGeoPlugin, flags: 'Geo_plugin_unit_test,unit_tests' },
# { scheme: AWSPredictionsPlugin, flags: 'Predictions_plugin_unit_test,unit_tests' },
# { scheme: AWSPinpointAnalyticsPlugin, flags: 'Analytics_plugin_unit_test,unit_tests' },
# { scheme: AWSPinpointPushNotificationsPlugin, flags: 'PushNotifications_plugin_unit_test,unit_tests' },
# { scheme: AWSS3StoragePlugin, flags: 'Storage_plugin_unit_test,unit_tests' },
# { scheme: CoreMLPredictionsPlugin, flags: 'CoreMLPredictions_plugin_unit_test,unit_tests' }
# ]
# uses: ./.github/workflows/upload_coverage_report.yml
# with:
# scheme: ${{ matrix.file.scheme }}
# flags: ${{ matrix.file.flags }}
report-coverage:
if: ${{ vars.DISABLE_COVERAGE_REPORT != 'true' }}
name: ${{ matrix.file.scheme }} Unit Tests
needs: [targets-with-coverage]
strategy:
fail-fast: false
matrix:
file: [
{ scheme: Amplify, flags: 'Amplify,unit_tests' },
{ scheme: AWSPluginsCore, flags: 'AWSPluginsCore,unit_tests' },
{ scheme: AWSAPIPlugin, flags: 'API_plugin_unit_test,unit_tests' },
{ scheme: AWSCloudWatchLoggingPlugin, flags: 'Logging_plugin_unit_test,unit_tests' },
{ scheme: AWSCognitoAuthPlugin, flags: 'Auth_plugin_unit_test,unit_tests' },
{ scheme: AWSDataStorePlugin, flags: 'DataStore_plugin_unit_test,unit_tests' },
{ scheme: AWSLocationGeoPlugin, flags: 'Geo_plugin_unit_test,unit_tests' },
{ scheme: AWSPredictionsPlugin, flags: 'Predictions_plugin_unit_test,unit_tests' },
{ scheme: AWSPinpointAnalyticsPlugin, flags: 'Analytics_plugin_unit_test,unit_tests' },
{ scheme: AWSPinpointPushNotificationsPlugin, flags: 'PushNotifications_plugin_unit_test,unit_tests' },
{ scheme: AWSS3StoragePlugin, flags: 'Storage_plugin_unit_test,unit_tests' },
{ scheme: CoreMLPredictionsPlugin, flags: 'CoreMLPredictions_plugin_unit_test,unit_tests' }
]
uses: ./.github/workflows/upload_coverage_report.yml
with:
scheme: ${{ matrix.file.scheme }}
flags: ${{ matrix.file.flags }}

unit-test-pass-confirmation:
runs-on: ubuntu-latest
name: Confirm Passing Unit Tests
if: ${{ !cancelled() }}
needs: [
unit-tests-with-coverage,
unit-tests-without-coverage
targets-with-coverage,
targets-without-coverage
]
env:
EXIT_CODE: ${{ contains(needs.*.result, 'failure') && 1 || 0 }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Combine

class CancellableAsyncStream<Element>: AsyncSequence {

typealias AsyncIterator = AsyncStream<Element>.AsyncIterator
private let asyncStream: AsyncStream<Element>
private let cancellable: AnyCancellable?

deinit {
cancel()
}

init(asyncStream: AsyncStream<Element>, cancellable: AnyCancellable?) {
self.asyncStream = asyncStream
self.cancellable = cancellable
}

convenience init(with publisher: AnyPublisher<Element, Never>) {
var cancellable: AnyCancellable?
self.init(asyncStream: AsyncStream { continuation in
cancellable = publisher.sink { _ in
continuation.finish()
} receiveValue: {
continuation.yield($0)
}
}, cancellable: cancellable)
}

func makeAsyncIterator() -> AsyncStream<Element>.AsyncIterator {
asyncStream.makeAsyncIterator()
}

func cancel() {
cancellable?.cancel()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

import Foundation

/// Captures a weak reference to the value
class WeakWrapper<T> where T: AnyObject {
private(set) weak var value: T?
init(_ value: T) {
self.value = value
}
}
import Combine

/// Models, evolves, and processes effects for a system.
///
Expand All @@ -31,15 +23,18 @@ actor StateMachine<
EnvironmentType: Environment
> where StateType: State {

/// AsyncSequences are invoked a minimum of one time: Each sequence receives the current
/// state as soon as `listen()` is invoked, and will receive each subsequent state change.
typealias StateChangeSequence = StateAsyncSequence<StateType>

private let environment: EnvironmentType
private let resolver: AnyResolver<StateType>

private(set) var currentState: StateType
private var subscribers: [WeakWrapper<StateAsyncSequence<StateType>>]
public var currentState: StateType {
currentStateSubject.value
}

private let currentStateSubject: CurrentValueSubject<StateType, Never>

deinit {
currentStateSubject.send(completion: .finished)
}

init<ResolverType>(
resolver: ResolverType,
Expand All @@ -48,22 +43,16 @@ actor StateMachine<
) where ResolverType: StateMachineResolver, ResolverType.StateType == StateType {
self.resolver = resolver.eraseToAnyResolver()
self.environment = environment
self.currentState = initialState ?? resolver.defaultState

self.subscribers = []
self.currentStateSubject = CurrentValueSubject(initialState ?? resolver.defaultState)
}

/// Start listening to state change updates. The current state and all subsequent state changes will be sent to the sequence.
///
/// - Returns: An async sequence that get states asynchronously
func listen() -> StateChangeSequence {
let sequence = StateAsyncSequence<StateType>()
let currentState = self.currentState
let wrappedSequence = WeakWrapper(sequence)
subscribers.append(wrappedSequence)
sequence.send(currentState)
return sequence
func listen() -> CancellableAsyncStream<StateType> {
CancellableAsyncStream(with: currentStateSubject.eraseToAnyPublisher())
}

}

extension StateMachine: EventDispatcher {
Expand All @@ -88,33 +77,11 @@ extension StateMachine: EventDispatcher {
)

if currentState != resolution.newState {
currentState = resolution.newState
subscribers.removeAll { item in
!notify(subscriberElement: item, about: resolution.newState)
}
currentStateSubject.send(resolution.newState)
}
execute(resolution.actions)
}

/// - Parameters:
/// - subscriberElement: A weak wrapped async sequence
/// - newState: The new state to be sent
/// - Returns: true if the subscriber was notified, false if the wrapper reference was nil or a cancellation was pending
private func notify(
subscriberElement: WeakWrapper<StateChangeSequence>,
about newState: StateType
) -> Bool {

// If weak reference has become nil, do not process, and return false so caller can remove
// the subscription from the subscribers list
guard let sequence = subscriberElement.value else {
return false
}

sequence.send(newState)
return true
}

private func execute(_ actions: [Action]) {
guard !actions.isEmpty else {
return
Expand Down

0 comments on commit bd6e02a

Please sign in to comment.