diff --git a/Sources/UntoldEditor/Editor/Inspector/StaticBatchingEditorView.swift b/Sources/UntoldEditor/Editor/Inspector/StaticBatchingEditorView.swift index 628d0d2..f11c8a9 100644 --- a/Sources/UntoldEditor/Editor/Inspector/StaticBatchingEditorView.swift +++ b/Sources/UntoldEditor/Editor/Inspector/StaticBatchingEditorView.swift @@ -104,9 +104,9 @@ struct StaticBatchingEditorView: View { // Update checkbox state when view appears staticBatchCheckboxState = isMarkedAsStatic(entityId: entityId) } - .onChange(of: entityId) { newEntityId in + .onChange(of: entityId) { // Update checkbox state when entity selection changes - staticBatchCheckboxState = isMarkedAsStatic(entityId: newEntityId) + staticBatchCheckboxState = isMarkedAsStatic(entityId: entityId) } } diff --git a/Sources/UntoldEditor/Editor/Shared/LoadingIndicatorView.swift b/Sources/UntoldEditor/Editor/Shared/LoadingIndicatorView.swift index e932fed..e824e77 100644 --- a/Sources/UntoldEditor/Editor/Shared/LoadingIndicatorView.swift +++ b/Sources/UntoldEditor/Editor/Shared/LoadingIndicatorView.swift @@ -9,6 +9,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. // +import Combine import SwiftUI import UntoldEngine diff --git a/Sources/UntoldEditor/Editor/Shared/MinimalLoadingIndicator.swift b/Sources/UntoldEditor/Editor/Shared/MinimalLoadingIndicator.swift index 2604b4a..712fda4 100644 --- a/Sources/UntoldEditor/Editor/Shared/MinimalLoadingIndicator.swift +++ b/Sources/UntoldEditor/Editor/Shared/MinimalLoadingIndicator.swift @@ -9,6 +9,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. // +import Combine import SwiftUI import UntoldEngine diff --git a/Sources/UntoldEditor/Editor/Tasks/TasksPanelView.swift b/Sources/UntoldEditor/Editor/Tasks/TasksPanelView.swift index 9d08134..d78b56c 100644 --- a/Sources/UntoldEditor/Editor/Tasks/TasksPanelView.swift +++ b/Sources/UntoldEditor/Editor/Tasks/TasksPanelView.swift @@ -13,6 +13,7 @@ // spinner plus elapsed time, and a cancel button for jobs that support it. // +import Combine import SwiftUI struct TasksPanelView: View { diff --git a/Sources/UntoldEditor/Editor/Window/EditorView+Entities.swift b/Sources/UntoldEditor/Editor/Window/EditorView+Entities.swift index 2ae1b5e..e4ad914 100644 --- a/Sources/UntoldEditor/Editor/Window/EditorView+Entities.swift +++ b/Sources/UntoldEditor/Editor/Window/EditorView+Entities.swift @@ -142,8 +142,6 @@ extension EditorView { var forward = forwardDirectionVector(from: cameraComponent.rotation) forward *= -1.0 - let camPosition = cameraComponent.localPosition - let spawnPosition = camPosition + forward * spawnDistance translateTo(entityId: entityId, position: simd_float3(0.0, 0.0, 0.0)) selectionManager.selectedEntity = entityId diff --git a/Sources/UntoldEditor/Systems/ScriptProjectManager.swift b/Sources/UntoldEditor/Systems/ScriptProjectManager.swift index 15f9158..01f7a28 100644 --- a/Sources/UntoldEditor/Systems/ScriptProjectManager.swift +++ b/Sources/UntoldEditor/Systems/ScriptProjectManager.swift @@ -57,7 +57,7 @@ class ScriptProjectManager { // MARK: - Initialize Project func initializeProject() throws { - guard let basePath = EditorAssetBasePath.shared.basePath else { + guard EditorAssetBasePath.shared.basePath != nil else { throw ScriptProjectError.noAssetBasePath } diff --git a/Tests/UntoldEditorTests/AssetImportCopyTests.swift b/Tests/UntoldEditorTests/AssetImportCopyTests.swift index 81dc0e3..5d802a0 100644 --- a/Tests/UntoldEditorTests/AssetImportCopyTests.swift +++ b/Tests/UntoldEditorTests/AssetImportCopyTests.swift @@ -188,7 +188,7 @@ final class AssetImportCopyTests: XCTestCase { let destination = base.appendingPathComponent("copy.ply") var reports: [AssetCopyProgress] = [] - try copyAssetItem(from: source, to: destination, allowClone: false) { reports.append($0) } + try copyAssetItem(from: source, to: destination, allowClone: false, progress: { reports.append($0) }) XCTAssertEqual(try Data(contentsOf: destination), payload) XCTAssertEqual(reports.last, AssetCopyProgress(copied: Int64(payload.count), total: Int64(payload.count))) @@ -212,7 +212,7 @@ final class AssetImportCopyTests: XCTestCase { let destination = base.appendingPathComponent("copy", isDirectory: true) var last: AssetCopyProgress? - try copyAssetItem(from: source, to: destination, allowClone: false) { last = $0 } + try copyAssetItem(from: source, to: destination, allowClone: false, progress: { last = $0 }) XCTAssertEqual(try Data(contentsOf: destination.appendingPathComponent("Textures/albedo.png")), Data("bb".utf8)) XCTAssertEqual(try Data(contentsOf: destination.appendingPathComponent("material.json")), Data("a".utf8)) diff --git a/Tests/UntoldEditorTests/CreateProjectViewTests.swift b/Tests/UntoldEditorTests/CreateProjectViewTests.swift index 48aa722..b56127d 100644 --- a/Tests/UntoldEditorTests/CreateProjectViewTests.swift +++ b/Tests/UntoldEditorTests/CreateProjectViewTests.swift @@ -18,6 +18,22 @@ import SwiftUI import XCTest final class CreateProjectViewTests: XCTestCase { + // MARK: - Helper mirroring CreateProjectView's target-index mapping + + /// Mirrors the `selectedTarget` → `BuildTarget` switch in `CreateProjectView.createBuildSettings()`. + /// Takes the index as a parameter (rather than inlining the switch on a literal in each test) + /// so the compiler can't prove branches unreachable and warn about dead code. + private func buildTarget(forSelectedTarget selectedTarget: Int) -> BuildTarget { + switch selectedTarget { + case 0: return .macOS(deployment: .v15) + case 1: return .iOS(deployment: .v17) + case 2: return .iOS(deployment: .v17) + case 3: return .visionOS(deployment: .v26) + case 4: return .multi(macOS: .v15, iOS: .v17, visionOS: .v26) + default: return .macOS(deployment: .v15) + } + } + // MARK: - Helper for reading @State defaults /// Reads the initial value of one of the view's `@State` properties using reflection. @@ -512,11 +528,7 @@ final class CreateProjectViewTests: XCTestCase { let selectedTarget = 0 // Act - let target: BuildTarget - switch selectedTarget { - case 0: target = .macOS(deployment: .v15) - default: target = .macOS(deployment: .v15) - } + let target = buildTarget(forSelectedTarget: selectedTarget) // Assert if case .macOS = target { @@ -531,11 +543,7 @@ final class CreateProjectViewTests: XCTestCase { let selectedTarget = 1 // Act - let target: BuildTarget - switch selectedTarget { - case 1: target = .iOS(deployment: .v17) - default: target = .macOS(deployment: .v15) - } + let target = buildTarget(forSelectedTarget: selectedTarget) // Assert if case .iOS = target { @@ -551,11 +559,7 @@ final class CreateProjectViewTests: XCTestCase { let isIOSAR = (selectedTarget == 2) // Act - let target: BuildTarget - switch selectedTarget { - case 2: target = .iOS(deployment: .v17) - default: target = .macOS(deployment: .v15) - } + let target = buildTarget(forSelectedTarget: selectedTarget) // Assert if case .iOS = target { @@ -570,11 +574,7 @@ final class CreateProjectViewTests: XCTestCase { let selectedTarget = 3 // Act - let target: BuildTarget - switch selectedTarget { - case 3: target = .visionOS(deployment: .v26) - default: target = .macOS(deployment: .v15) - } + let target = buildTarget(forSelectedTarget: selectedTarget) // Assert if case .visionOS = target { @@ -589,11 +589,7 @@ final class CreateProjectViewTests: XCTestCase { let selectedTarget = 4 // Act - let target: BuildTarget - switch selectedTarget { - case 4: target = .multi(macOS: .v15, iOS: .v17, visionOS: .v26) - default: target = .macOS(deployment: .v15) - } + let target = buildTarget(forSelectedTarget: selectedTarget) // Assert if case .multi = target { @@ -608,15 +604,7 @@ final class CreateProjectViewTests: XCTestCase { let selectedTarget = 999 // Invalid index // Act - let target: BuildTarget - switch selectedTarget { - case 0: target = .macOS(deployment: .v15) - case 1: target = .iOS(deployment: .v17) - case 2: target = .iOS(deployment: .v17) - case 3: target = .visionOS(deployment: .v26) - case 4: target = .multi(macOS: .v15, iOS: .v17, visionOS: .v26) - default: target = .macOS(deployment: .v15) - } + let target = buildTarget(forSelectedTarget: selectedTarget) // Assert if case .macOS = target { diff --git a/Tests/UntoldEditorTests/EditorControllerTests.swift b/Tests/UntoldEditorTests/EditorControllerTests.swift index cb23e3a..92c261d 100644 --- a/Tests/UntoldEditorTests/EditorControllerTests.swift +++ b/Tests/UntoldEditorTests/EditorControllerTests.swift @@ -125,7 +125,8 @@ final class EditorControllerTests: XCTestCase { func test_editorController_implementsSelectionDelegate() { // Assert - XCTAssertNotNil(controller as? SelectionDelegate, "Should implement SelectionDelegate protocol") + let delegate: SelectionDelegate? = controller + XCTAssertNotNil(delegate, "Should implement SelectionDelegate protocol") } func test_editorController_didSelectEntity_updatesSelectionManager() { diff --git a/Tests/UntoldEditorTests/EnvironmentViewTests.swift b/Tests/UntoldEditorTests/EnvironmentViewTests.swift index c0de821..780872b 100644 --- a/Tests/UntoldEditorTests/EnvironmentViewTests.swift +++ b/Tests/UntoldEditorTests/EnvironmentViewTests.swift @@ -97,8 +97,6 @@ final class EnvironmentViewTests: XCTestCase { let hdrFilePath = hdr.appendingPathComponent("test_environment.hdr") FileManager.default.createFile(atPath: hdrFilePath.path, contents: Data()) - let hdrAsset = Asset(name: "test_environment.hdr", category: "HDR", path: hdrFilePath, isFolder: false) - // Verify the HDR file exists XCTAssertTrue(FileManager.default.fileExists(atPath: hdrFilePath.path), "HDR file should exist") diff --git a/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift b/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift index 8af792c..c9a5819 100644 --- a/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift +++ b/Tests/UntoldEditorTests/SceneHierarchyViewTests.swift @@ -205,8 +205,8 @@ final class SceneHierarchyViewTests: XCTestCase { func test_sceneGraphModel_returnsRootEntitiesForNilParent() { // Arrange - createEntity() - createEntity() + _ = createEntity() + _ = createEntity() // Refresh to cache the hierarchy sceneGraphModel.refreshHierarchy() @@ -358,17 +358,17 @@ final class SceneHierarchyViewTests: XCTestCase { // MARK: - Entity Hierarchy Tests - func test_sceneGraphModel_refreshHierarchy() { + func test_sceneGraphModel_refreshHierarchy() throws { // Arrange: Create some entities - createEntity() - createEntity() - createEntity() + _ = createEntity() + _ = createEntity() + _ = createEntity() // Act: Refresh hierarchy sceneGraphModel.refreshHierarchy() // Assert: The childrenMap should be populated - let mirror = Mirror(reflecting: sceneGraphModel) + let mirror = try Mirror(reflecting: XCTUnwrap(sceneGraphModel)) if let childrenMap = mirror.descendant("childrenMap") as? [EntityID: [EntityID]] { // The map should exist (though it might be empty or contain root entities) XCTAssertNotNil(childrenMap, "Children map should be populated after refresh") @@ -393,7 +393,7 @@ final class SceneHierarchyViewTests: XCTestCase { // Arrange let entity = createEntity() - let row = EntityRow( + _ = EntityRow( entityid: entity, entityName: "TestEntity", selectionManager: selectionManager