From 3b8bd7e4e6d89172bce866129e0cba3bdbe8797d Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 14 Feb 2021 18:33:18 +0000 Subject: [PATCH 1/6] Use immediate scheduler in TestRenderer This allows running our test suite on WASI too, which doesn't have Dispatch and also can't wait on XCTest expectations. Previously none of our tests (especially runtime reflection tests) ran on WASI. --- .github/workflows/ci.yml | 4 +- .../TokamakTestRenderer/TestRenderer.swift | 16 +-- Tests/TokamakTests/ReconcilerTests.swift | 133 +++++++----------- 3 files changed, 55 insertions(+), 98 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1171a85d..6247cf359 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,14 +6,14 @@ on: branches: [main] jobs: - swiftwasm_build: + swiftwasm_test: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - uses: swiftwasm/swiftwasm-action@v5.3 with: - shell-action: carton bundle --product TokamakDemo + shell-action: carton test && carton bundle --product TokamakDemo core_macos_build: runs-on: macos-11.0 diff --git a/Sources/TokamakTestRenderer/TestRenderer.swift b/Sources/TokamakTestRenderer/TestRenderer.swift index 32314bf8d..768fccb5d 100644 --- a/Sources/TokamakTestRenderer/TestRenderer.swift +++ b/Sources/TokamakTestRenderer/TestRenderer.swift @@ -15,23 +15,11 @@ // Created by Max Desiatov on 21/12/2018. // -#if os(WASI) -import JavaScriptKit -#else -import Dispatch -#endif import TokamakCore public func testScheduler(closure: @escaping () -> ()) { - #if os(WASI) - let fn = JSClosure { _ -> JSValue in - closure() - return .undefined - } - _ = JSObject.global.setTimeout!(fn, 0) - #else - DispatchQueue.main.async(execute: closure) - #endif + // immediate scheduler on all platforms for easier debugging and support on all platforms + closure() } public final class TestRenderer: Renderer { diff --git a/Tests/TokamakTests/ReconcilerTests.swift b/Tests/TokamakTests/ReconcilerTests.swift index 63a87e2b6..cc9e66a78 100644 --- a/Tests/TokamakTests/ReconcilerTests.swift +++ b/Tests/TokamakTests/ReconcilerTests.swift @@ -77,24 +77,16 @@ final class ReconcilerTests: XCTestCase { button.action() - let e = expectation(description: "rerender") - - testScheduler { - XCTAssertTrue(root.view.view is EmptyView) - XCTAssertEqual(root.subviews.count, 1) - let newStack = root.subviews[0].subviews[0] - XCTAssert(stack === newStack) - XCTAssertTrue(stack.view.view is VStack, Text)>>) - XCTAssertEqual(stack.subviews.count, 2) - XCTAssertTrue(stack.subviews[0].view.view is _Button) - XCTAssertTrue(stack.subviews[1].view.view is Text) - XCTAssertTrue(originalLabel === newStack.subviews[1]) - XCTAssertEqual((stack.subviews[1].view.view as? Text)?.verbatim, "43") - - e.fulfill() - } - - wait(for: [e], timeout: 30) + XCTAssertTrue(root.view.view is EmptyView) + XCTAssertEqual(root.subviews.count, 1) + let newStack = root.subviews[0].subviews[0] + XCTAssert(stack === newStack) + XCTAssertTrue(stack.view.view is VStack, Text)>>) + XCTAssertEqual(stack.subviews.count, 2) + XCTAssertTrue(stack.subviews[0].view.view is _Button) + XCTAssertTrue(stack.subviews[1].view.view is Text) + XCTAssertTrue(originalLabel === newStack.subviews[1]) + XCTAssertEqual((stack.subviews[1].view.view as? Text)?.verbatim, "43") } func testDoubleUpdate() { @@ -111,44 +103,34 @@ final class ReconcilerTests: XCTestCase { button.action() - let e = expectation(description: "rerender") - - testScheduler { - XCTAssertTrue(root.view.view is EmptyView) - XCTAssertEqual(root.subviews.count, 1) - let newStack = root.subviews[0].subviews[0] - XCTAssert(stack === newStack) - XCTAssertTrue(stack.view.view is VStack, Text)>>) - XCTAssertEqual(stack.subviews.count, 2) - XCTAssertTrue(stack.subviews[0].view.view is _Button) - XCTAssertTrue(stack.subviews[1].view.view is Text) - XCTAssertTrue(originalLabel === newStack.subviews[1]) - XCTAssertEqual((stack.subviews[1].view.view as? Text)?.verbatim, "43") - - guard let button = stack.subviews[0].view.view as? _Button else { - XCTAssert(false, "counter has no button") - return - } + XCTAssertTrue(root.view.view is EmptyView) + XCTAssertEqual(root.subviews.count, 1) + let newStack = root.subviews[0].subviews[0] + XCTAssert(stack === newStack) + XCTAssertTrue(stack.view.view is VStack, Text)>>) + XCTAssertEqual(stack.subviews.count, 2) + XCTAssertTrue(stack.subviews[0].view.view is _Button) + XCTAssertTrue(stack.subviews[1].view.view is Text) + XCTAssertTrue(originalLabel === newStack.subviews[1]) + XCTAssertEqual((stack.subviews[1].view.view as? Text)?.verbatim, "43") - button.action() - - testScheduler { - XCTAssertTrue(root.view.view is EmptyView) - XCTAssertEqual(root.subviews.count, 1) - let newStack = root.subviews[0].subviews[0] - XCTAssert(stack === newStack) - XCTAssertTrue(stack.view.view is VStack, Text)>>) - XCTAssertEqual(stack.subviews.count, 2) - XCTAssertTrue(stack.subviews[0].view.view is _Button) - XCTAssertTrue(stack.subviews[1].view.view is Text) - XCTAssertTrue(originalLabel === newStack.subviews[1]) - XCTAssertEqual((stack.subviews[1].view.view as? Text)?.verbatim, "44") - - e.fulfill() - } + guard let newButton = stack.subviews[0].view.view as? _Button else { + XCTAssert(false, "counter has no button") + return } - wait(for: [e], timeout: 1) + newButton.action() + + XCTAssertTrue(root.view.view is EmptyView) + XCTAssertEqual(root.subviews.count, 1) + let newestStack = root.subviews[0].subviews[0] + XCTAssert(stack === newestStack) + XCTAssertTrue(stack.view.view is VStack, Text)>>) + XCTAssertEqual(stack.subviews.count, 2) + XCTAssertTrue(stack.subviews[0].view.view is _Button) + XCTAssertTrue(stack.subviews[1].view.view is Text) + XCTAssertTrue(originalLabel === newStack.subviews[1]) + XCTAssertEqual((stack.subviews[1].view.view as? Text)?.verbatim, "44") } func testUnmount() { @@ -163,38 +145,25 @@ final class ReconcilerTests: XCTestCase { button.action() - let e = expectation(description: "rerender") - - testScheduler { - // rerender completed here, schedule another one - guard let button = stack.subviews[0].view.view as? _Button else { - XCTAssert(false, "counter has no button") - return - } - - button.action() - - testScheduler { - guard let button = stack.subviews[0].view.view as? _Button else { - XCTAssert(false, "counter has no button") - return - } - - button.action() + guard let newButton = stack.subviews[0].view.view as? _Button else { + XCTAssert(false, "counter has no button") + return + } - testScheduler { - XCTAssertTrue(root.view.view is EmptyView) - XCTAssertEqual(root.subviews.count, 1) - let newStack = root.subviews[0].subviews[0] - XCTAssert(stack === newStack) - XCTAssertTrue(stack.view.view is VStack) - XCTAssertEqual(stack.subviews.count, 1) + newButton.action() - e.fulfill() - } - } + guard let newestButton = stack.subviews[0].view.view as? _Button else { + XCTAssert(false, "counter has no button") + return } - wait(for: [e], timeout: 1) + newestButton.action() + + XCTAssertTrue(root.view.view is EmptyView) + XCTAssertEqual(root.subviews.count, 1) + let newStack = root.subviews[0].subviews[0] + XCTAssert(stack === newStack) + XCTAssertTrue(stack.view.view is VStack) + XCTAssertEqual(stack.subviews.count, 1) } } From 0607cbae59e6f8c28fb7702fac18d5e5f5cbefa3 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 14 Feb 2021 18:37:46 +0000 Subject: [PATCH 2/6] Run `carton test` and `carton bundle` in separate jobs --- .github/workflows/ci.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6247cf359..12ab1895d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,15 @@ on: branches: [main] jobs: + swiftwasm_bundle: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + - uses: swiftwasm/swiftwasm-action@v5.3 + with: + shell-action: carton bundle --product TokamakDemo + swiftwasm_test: runs-on: ubuntu-20.04 @@ -13,7 +22,7 @@ jobs: - uses: actions/checkout@v2 - uses: swiftwasm/swiftwasm-action@v5.3 with: - shell-action: carton test && carton bundle --product TokamakDemo + shell-action: carton test core_macos_build: runs-on: macos-11.0 From 73a8be29a73887996e9e614cf3e52ab815763ecf Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 14 Feb 2021 19:39:15 +0000 Subject: [PATCH 3/6] Bump year in the `LICENSE` file --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 15f0c2ce7..c7394fc6e 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright 2018-2020 Digital Signal Limited and Tokamak Contributors +Copyright 2018-2021 Digital Signal Limited and Tokamak Contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From f21cbfb94aabe12525e1b06b5129d917d420eb30 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 14 Feb 2021 21:16:53 +0000 Subject: [PATCH 4/6] Add reconciler stress tests for elaborate testing --- .../Reflection/Layouts/FieldDescriptor.swift | 3 +- .../TokamakCore/Views/Containers/List.swift | 1 - .../TokamakTestRenderer/TestRenderer.swift | 10 +++ Sources/TokamakTestRenderer/WindowGroup.swift | 21 ++++++ .../TokamakTests/ReconcilerStressTests.swift | 71 +++++++++++++++++++ 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 Sources/TokamakTestRenderer/WindowGroup.swift create mode 100644 Tests/TokamakTests/ReconcilerStressTests.swift diff --git a/Sources/TokamakCore/Reflection/Layouts/FieldDescriptor.swift b/Sources/TokamakCore/Reflection/Layouts/FieldDescriptor.swift index 74c9feff9..4f238261b 100644 --- a/Sources/TokamakCore/Reflection/Layouts/FieldDescriptor.swift +++ b/Sources/TokamakCore/Reflection/Layouts/FieldDescriptor.swift @@ -30,8 +30,7 @@ func _getTypeByMangledNameInContext( _ nameLength: UInt, _ genericContext: UnsafeRawPointer?, _ genericArguments: UnsafeRawPointer? -) - -> Any.Type? +) -> Any.Type? /// https://github.com/apple/swift/blob/f2c42509628bed66bf5b8ee02fae778a2ba747a1/include/swift/Reflection/Records.h#L160 struct FieldDescriptor { diff --git a/Sources/TokamakCore/Views/Containers/List.swift b/Sources/TokamakCore/Views/Containers/List.swift index e2f02e309..678284264 100644 --- a/Sources/TokamakCore/Views/Containers/List.swift +++ b/Sources/TokamakCore/Views/Containers/List.swift @@ -149,7 +149,6 @@ public extension List { init( _ data: Data, - id: KeyPath, selection: Binding>?, @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent diff --git a/Sources/TokamakTestRenderer/TestRenderer.swift b/Sources/TokamakTestRenderer/TestRenderer.swift index 768fccb5d..ed2e534e2 100644 --- a/Sources/TokamakTestRenderer/TestRenderer.swift +++ b/Sources/TokamakTestRenderer/TestRenderer.swift @@ -29,6 +29,16 @@ public final class TestRenderer: Renderer { reconciler!.rootTarget } + public init(_ app: A) { + reconciler = StackReconciler( + app: app, + target: TestView(EmptyView()), + environment: .init(), + renderer: self, + scheduler: testScheduler + ) + } + public init(_ view: V) { reconciler = StackReconciler( view: view, diff --git a/Sources/TokamakTestRenderer/WindowGroup.swift b/Sources/TokamakTestRenderer/WindowGroup.swift new file mode 100644 index 000000000..825369413 --- /dev/null +++ b/Sources/TokamakTestRenderer/WindowGroup.swift @@ -0,0 +1,21 @@ +// Copyright 2021 Tokamak contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import TokamakCore + +extension WindowGroup: SceneDeferredToRenderer { + public var deferredBody: AnyView { + AnyView(content) + } +} diff --git a/Tests/TokamakTests/ReconcilerStressTests.swift b/Tests/TokamakTests/ReconcilerStressTests.swift new file mode 100644 index 000000000..951b38d62 --- /dev/null +++ b/Tests/TokamakTests/ReconcilerStressTests.swift @@ -0,0 +1,71 @@ +// Copyright 2021 Tokamak contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import OpenCombine +import TokamakTestRenderer +import XCTest + +@testable import TokamakCore + +private struct SpookyHanger: App { + var body: some Scene { + WindowGroup("Spooky Hanger") { + NavigationView { + List { + ForEach(["Item 1"], id: \.self) { childRow in + NavigationLink( + destination: Text(childRow) + ) { + Text(childRow) + } + } + } + } + } + } + + static func _setTitle(_ title: String) {} + + /// Implemented by the renderer to mount the `App` + static func _launch(_ app: Self, _ rootEnvironment: EnvironmentValues) {} + + /// Implemented by the renderer to update the `App` on `ScenePhase` changes + var _phasePublisher: AnyPublisher { Empty().eraseToAnyPublisher() } + + /// Implemented by the renderer to update the `App` on `ColorScheme` changes + var _colorSchemePublisher: AnyPublisher { Empty().eraseToAnyPublisher() } +} + +final class ReconcilerStressTests: XCTestCase { + func testSpookyHanger() { + let renderer = TestRenderer(SpookyHanger()) + let root = renderer.rootTarget + + return + + let list = root.subviews[0].subviews[0] + + XCTAssertTrue( + root.view + .view is NavigationView>>> + ) + + guard let link = list.subviews[0].view.view as? NavigationLink else { + XCTAssert(false, "navigation has no link") + return + } + + _NavigationLinkProxy(link).activate() + } +} From c8f9854d31e1d7302a5d6e5c6699af3ea66a0ece Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 14 Feb 2021 21:21:50 +0000 Subject: [PATCH 5/6] Move default App implementation to TestRenderer --- Sources/TokamakTestRenderer/App.swift | 26 +++++++++++++++++++ .../TokamakTests/ReconcilerStressTests.swift | 11 -------- 2 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 Sources/TokamakTestRenderer/App.swift diff --git a/Sources/TokamakTestRenderer/App.swift b/Sources/TokamakTestRenderer/App.swift new file mode 100644 index 000000000..1789811aa --- /dev/null +++ b/Sources/TokamakTestRenderer/App.swift @@ -0,0 +1,26 @@ +// Copyright 2021 Tokamak contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import OpenCombine +import TokamakCore + +public extension App { + static func _setTitle(_ title: String) {} + + static func _launch(_ app: Self, _ rootEnvironment: EnvironmentValues) {} + + var _phasePublisher: AnyPublisher { Empty().eraseToAnyPublisher() } + + var _colorSchemePublisher: AnyPublisher { Empty().eraseToAnyPublisher() } +} diff --git a/Tests/TokamakTests/ReconcilerStressTests.swift b/Tests/TokamakTests/ReconcilerStressTests.swift index 951b38d62..cf37476a3 100644 --- a/Tests/TokamakTests/ReconcilerStressTests.swift +++ b/Tests/TokamakTests/ReconcilerStressTests.swift @@ -34,17 +34,6 @@ private struct SpookyHanger: App { } } } - - static func _setTitle(_ title: String) {} - - /// Implemented by the renderer to mount the `App` - static func _launch(_ app: Self, _ rootEnvironment: EnvironmentValues) {} - - /// Implemented by the renderer to update the `App` on `ScenePhase` changes - var _phasePublisher: AnyPublisher { Empty().eraseToAnyPublisher() } - - /// Implemented by the renderer to update the `App` on `ColorScheme` changes - var _colorSchemePublisher: AnyPublisher { Empty().eraseToAnyPublisher() } } final class ReconcilerStressTests: XCTestCase { From 69d06dcac6c7d992722f0ade8b14277d658a5b21 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 14 Feb 2021 21:32:10 +0000 Subject: [PATCH 6/6] Use OpenCombineShim instead of CombineShim --- Package.swift | 30 +++++++++++-------- Sources/CombineShim/CombineShim.swift | 19 ------------ Sources/TokamakCore/App/App.swift | 2 +- Sources/TokamakCore/App/AppStorage.swift | 4 +-- .../TokamakCore/App/Scenes/SceneStorage.swift | 4 +-- Sources/TokamakCore/App/_AnyApp.swift | 4 +-- .../TokamakCore/App/_StorageProvider.swift | 4 +-- .../Environment/EnvironmentObject.swift | 4 +-- .../Environment/EnvironmentValues.swift | 4 +-- .../TokamakCore/MountedViews/MountedApp.swift | 2 +- .../MountedCompositeElement.swift | 4 +-- .../MountedViews/MountedCompositeView.swift | 2 +- Sources/TokamakCore/StackReconciler.swift | 2 +- .../TokamakCore/State/ObservedObject.swift | 8 ++--- Sources/TokamakCore/State/StateObject.swift | 4 +-- Sources/TokamakDOM/App/App.swift | 4 +-- .../TokamakDOM/App/ColorSchemeObserver.swift | 4 +-- .../TokamakDOM/App/ScenePhaseObserver.swift | 4 +-- Sources/TokamakDOM/Storage/LocalStorage.swift | 4 +-- .../TokamakDOM/Storage/SessionStorage.swift | 4 +-- Sources/TokamakDOM/Storage/WebStorage.swift | 4 +-- Sources/TokamakGTK/App/App.swift | 4 +-- Sources/TokamakStaticHTML/App.swift | 4 +-- Sources/TokamakTestRenderer/App.swift | 2 +- .../TokamakTests/ReconcilerStressTests.swift | 1 - 25 files changed, 59 insertions(+), 73 deletions(-) delete mode 100644 Sources/CombineShim/CombineShim.swift diff --git a/Package.swift b/Package.swift index cc9b054e2..98f2847d9 100644 --- a/Package.swift +++ b/Package.swift @@ -62,17 +62,14 @@ let package = Package( // a module or a test suite. // Targets can depend on other targets in this package, and on products // in packages which this package depends on. - .target( - name: "CombineShim", - dependencies: [.product( - name: "OpenCombine", - package: "OpenCombine", - condition: .when(platforms: [.wasi, .linux]) - )] - ), .target( name: "TokamakCore", - dependencies: ["CombineShim"] + dependencies: [ + .product( + name: "OpenCombineShim", + package: "OpenCombine" + ), + ] ), .target( name: "TokamakShim", @@ -105,7 +102,13 @@ let package = Package( ), .target( name: "TokamakGTK", - dependencies: ["TokamakCore", "CGTK", "CGDK", "TokamakGTKCHelpers", "CombineShim"] + dependencies: [ + "TokamakCore", "CGTK", "CGDK", "TokamakGTKCHelpers", + .product( + name: "OpenCombineShim", + package: "OpenCombine" + ), + ] ), .target( name: "TokamakGTKDemo", @@ -135,15 +138,18 @@ let package = Package( .target( name: "TokamakDOM", dependencies: [ - "CombineShim", - "OpenCombineJS", "TokamakCore", "TokamakStaticHTML", + .product( + name: "OpenCombineShim", + package: "OpenCombine" + ), .product( name: "JavaScriptKit", package: "JavaScriptKit", condition: .when(platforms: [.wasi]) ), + "OpenCombineJS", ] ), .target( diff --git a/Sources/CombineShim/CombineShim.swift b/Sources/CombineShim/CombineShim.swift deleted file mode 100644 index d82f71560..000000000 --- a/Sources/CombineShim/CombineShim.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2020 Tokamak contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#if canImport(Combine) -@_exported import Combine -#else -@_exported import OpenCombine -#endif diff --git a/Sources/TokamakCore/App/App.swift b/Sources/TokamakCore/App/App.swift index 6a7d39941..7f0104549 100644 --- a/Sources/TokamakCore/App/App.swift +++ b/Sources/TokamakCore/App/App.swift @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/16/20. // -import CombineShim +import OpenCombineShim /// Provides the ability to set the title of the Scene. public protocol _TitledApp { diff --git a/Sources/TokamakCore/App/AppStorage.swift b/Sources/TokamakCore/App/AppStorage.swift index eb3b0dfa4..5a197c7f9 100644 --- a/Sources/TokamakCore/App/AppStorage.swift +++ b/Sources/TokamakCore/App/AppStorage.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/16/20. // -import CombineShim +import OpenCombineShim @propertyWrapper public struct AppStorage: DynamicProperty { let provider: _StorageProvider? diff --git a/Sources/TokamakCore/App/Scenes/SceneStorage.swift b/Sources/TokamakCore/App/Scenes/SceneStorage.swift index 00c28706c..960308905 100644 --- a/Sources/TokamakCore/App/Scenes/SceneStorage.swift +++ b/Sources/TokamakCore/App/Scenes/SceneStorage.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/17/20. // -import CombineShim +import OpenCombineShim /// The renderer must specify a default `_StorageProvider` before any `SceneStorage` /// values are accessed. diff --git a/Sources/TokamakCore/App/_AnyApp.swift b/Sources/TokamakCore/App/_AnyApp.swift index 488cf2f2a..fae083ae6 100644 --- a/Sources/TokamakCore/App/_AnyApp.swift +++ b/Sources/TokamakCore/App/_AnyApp.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/19/20. // -import CombineShim +import OpenCombineShim public struct _AnyApp: App { var app: Any diff --git a/Sources/TokamakCore/App/_StorageProvider.swift b/Sources/TokamakCore/App/_StorageProvider.swift index ac12e706a..3a27a2444 100644 --- a/Sources/TokamakCore/App/_StorageProvider.swift +++ b/Sources/TokamakCore/App/_StorageProvider.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/22/20. // -import CombineShim +import OpenCombineShim public protocol _StorageProvider { func store(key: String, value: Bool?) diff --git a/Sources/TokamakCore/Environment/EnvironmentObject.swift b/Sources/TokamakCore/Environment/EnvironmentObject.swift index e02d8c43f..7c4986cd3 100644 --- a/Sources/TokamakCore/Environment/EnvironmentObject.swift +++ b/Sources/TokamakCore/Environment/EnvironmentObject.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/7/20. // -import CombineShim +import OpenCombineShim @propertyWrapper public struct EnvironmentObject: DynamicProperty where ObjectType: ObservableObject diff --git a/Sources/TokamakCore/Environment/EnvironmentValues.swift b/Sources/TokamakCore/Environment/EnvironmentValues.swift index b13adbda5..1291c2c5f 100644 --- a/Sources/TokamakCore/Environment/EnvironmentValues.swift +++ b/Sources/TokamakCore/Environment/EnvironmentValues.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import CombineShim +import OpenCombineShim public struct EnvironmentValues: CustomStringConvertible { public var description: String { diff --git a/Sources/TokamakCore/MountedViews/MountedApp.swift b/Sources/TokamakCore/MountedViews/MountedApp.swift index f85c880d9..2cece9213 100644 --- a/Sources/TokamakCore/MountedViews/MountedApp.swift +++ b/Sources/TokamakCore/MountedViews/MountedApp.swift @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/19/20. // -import CombineShim +import OpenCombineShim // This is very similar to `MountedCompositeView`. However, the `mountedBody` // is the computed content of the specified `Scene`, instead of having child diff --git a/Sources/TokamakCore/MountedViews/MountedCompositeElement.swift b/Sources/TokamakCore/MountedViews/MountedCompositeElement.swift index 85f81fa69..3fbc0ec58 100644 --- a/Sources/TokamakCore/MountedViews/MountedCompositeElement.swift +++ b/Sources/TokamakCore/MountedViews/MountedCompositeElement.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2020 Tokamak contributors +// Copyright 2018-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/19/20. // -import CombineShim +import OpenCombineShim class MountedCompositeElement: MountedElement { let parentTarget: R.TargetType diff --git a/Sources/TokamakCore/MountedViews/MountedCompositeView.swift b/Sources/TokamakCore/MountedViews/MountedCompositeView.swift index b5a0e2f18..e9262206c 100644 --- a/Sources/TokamakCore/MountedViews/MountedCompositeView.swift +++ b/Sources/TokamakCore/MountedViews/MountedCompositeView.swift @@ -15,7 +15,7 @@ // Created by Max Desiatov on 03/12/2018. // -import CombineShim +import OpenCombineShim final class MountedCompositeView: MountedCompositeElement { override func mount( diff --git a/Sources/TokamakCore/StackReconciler.swift b/Sources/TokamakCore/StackReconciler.swift index 6adb043f7..9d501b43d 100644 --- a/Sources/TokamakCore/StackReconciler.swift +++ b/Sources/TokamakCore/StackReconciler.swift @@ -15,7 +15,7 @@ // Created by Max Desiatov on 28/11/2018. // -import CombineShim +import OpenCombineShim /** A class that reconciles a "raw" tree of element values (such as `App`, `Scene` and `View`, all coming from `body` or `deferredBody` properties) with a tree of mounted element instances diff --git a/Sources/TokamakCore/State/ObservedObject.swift b/Sources/TokamakCore/State/ObservedObject.swift index c1a56f2cb..5268552d5 100644 --- a/Sources/TokamakCore/State/ObservedObject.swift +++ b/Sources/TokamakCore/State/ObservedObject.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import CombineShim +import OpenCombineShim -public typealias ObservableObject = CombineShim.ObservableObject -public typealias Published = CombineShim.Published +public typealias ObservableObject = OpenCombineShim.ObservableObject +public typealias Published = OpenCombineShim.Published protocol ObservedProperty: DynamicProperty { var objectWillChange: AnyPublisher<(), Never> { get } diff --git a/Sources/TokamakCore/State/StateObject.swift b/Sources/TokamakCore/State/StateObject.swift index 51aef0a46..5f2a87c8d 100644 --- a/Sources/TokamakCore/State/StateObject.swift +++ b/Sources/TokamakCore/State/StateObject.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import CombineShim +import OpenCombineShim @propertyWrapper public struct StateObject: DynamicProperty { diff --git a/Sources/TokamakDOM/App/App.swift b/Sources/TokamakDOM/App/App.swift index 75fec0513..d679d6fba 100644 --- a/Sources/TokamakDOM/App/App.swift +++ b/Sources/TokamakDOM/App/App.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ // Created by Carson Katri on 7/16/20. // -import CombineShim import JavaScriptKit +import OpenCombineShim import TokamakCore import TokamakStaticHTML diff --git a/Sources/TokamakDOM/App/ColorSchemeObserver.swift b/Sources/TokamakDOM/App/ColorSchemeObserver.swift index f8148c514..18c52b2e4 100644 --- a/Sources/TokamakDOM/App/ColorSchemeObserver.swift +++ b/Sources/TokamakDOM/App/ColorSchemeObserver.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import CombineShim import JavaScriptKit +import OpenCombineShim enum ColorSchemeObserver { static var publisher = CurrentValueSubject( diff --git a/Sources/TokamakDOM/App/ScenePhaseObserver.swift b/Sources/TokamakDOM/App/ScenePhaseObserver.swift index acb03f932..c5a567a54 100644 --- a/Sources/TokamakDOM/App/ScenePhaseObserver.swift +++ b/Sources/TokamakDOM/App/ScenePhaseObserver.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import CombineShim import JavaScriptKit +import OpenCombineShim enum ScenePhaseObserver { static var publisher = CurrentValueSubject(.active) diff --git a/Sources/TokamakDOM/Storage/LocalStorage.swift b/Sources/TokamakDOM/Storage/LocalStorage.swift index ab16c0b15..b0648eab0 100644 --- a/Sources/TokamakDOM/Storage/LocalStorage.swift +++ b/Sources/TokamakDOM/Storage/LocalStorage.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ // Created by Carson Katri on 7/20/20. // -import CombineShim import JavaScriptKit +import OpenCombineShim import TokamakCore private let rootPublisher = ObservableObjectPublisher() diff --git a/Sources/TokamakDOM/Storage/SessionStorage.swift b/Sources/TokamakDOM/Storage/SessionStorage.swift index 8719ad51b..52108bfa9 100644 --- a/Sources/TokamakDOM/Storage/SessionStorage.swift +++ b/Sources/TokamakDOM/Storage/SessionStorage.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ // Created by Carson Katri on 7/20/20. // -import CombineShim import JavaScriptKit +import OpenCombineShim import TokamakCore private let sessionStorage = JSObject.global.sessionStorage.object! diff --git a/Sources/TokamakDOM/Storage/WebStorage.swift b/Sources/TokamakDOM/Storage/WebStorage.swift index 9d959ae7b..2daecf53f 100644 --- a/Sources/TokamakDOM/Storage/WebStorage.swift +++ b/Sources/TokamakDOM/Storage/WebStorage.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ // Created by Carson Katri on 7/21/20. // -import CombineShim import JavaScriptKit +import OpenCombineShim import TokamakCore protocol WebStorage { diff --git a/Sources/TokamakGTK/App/App.swift b/Sources/TokamakGTK/App/App.swift index fa000b4e1..1dc13e6de 100644 --- a/Sources/TokamakGTK/App/App.swift +++ b/Sources/TokamakGTK/App/App.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ // import CGTK -import CombineShim import Dispatch +import OpenCombineShim import TokamakCore public extension App { diff --git a/Sources/TokamakStaticHTML/App.swift b/Sources/TokamakStaticHTML/App.swift index 1f89423af..22b509099 100644 --- a/Sources/TokamakStaticHTML/App.swift +++ b/Sources/TokamakStaticHTML/App.swift @@ -1,4 +1,4 @@ -// Copyright 2020 Tokamak contributors +// Copyright 2020-2021 Tokamak contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ // Created by Carson Katri on 7/31/20. // -import CombineShim +import OpenCombineShim import TokamakCore public extension App { diff --git a/Sources/TokamakTestRenderer/App.swift b/Sources/TokamakTestRenderer/App.swift index 1789811aa..42738bef4 100644 --- a/Sources/TokamakTestRenderer/App.swift +++ b/Sources/TokamakTestRenderer/App.swift @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import OpenCombine +import OpenCombineShim import TokamakCore public extension App { diff --git a/Tests/TokamakTests/ReconcilerStressTests.swift b/Tests/TokamakTests/ReconcilerStressTests.swift index cf37476a3..00d20dfd6 100644 --- a/Tests/TokamakTests/ReconcilerStressTests.swift +++ b/Tests/TokamakTests/ReconcilerStressTests.swift @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import OpenCombine import TokamakTestRenderer import XCTest