From 03d6a2d7f0ec58164da1ea31c7ac972fc08fd235 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Mon, 8 Jul 2024 11:57:12 -0400 Subject: [PATCH] feat: More tests --- .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../EquipmentMeasurementForm.swift | 6 +- .../EquipmentSettingsForm.swift | 6 +- .../EquipmentMeasurementFormTests.swift | 138 ++++++++++++++++++ .../EquipmentSettingsFormTests.swift | 75 ++++++++++ 5 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 EstimatedPressures.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 Tests/PressureEstimationsFeatureTests/EquipmentMeasurementFormTests.swift diff --git a/EstimatedPressures.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/EstimatedPressures.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/EstimatedPressures.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/Sources/PressureEstimationsFeature/EquipmentMeasurementForm.swift b/Sources/PressureEstimationsFeature/EquipmentMeasurementForm.swift index cee0b5f..34652a8 100644 --- a/Sources/PressureEstimationsFeature/EquipmentMeasurementForm.swift +++ b/Sources/PressureEstimationsFeature/EquipmentMeasurementForm.swift @@ -196,7 +196,9 @@ public struct EquipmentMeasurementForm { ) } state.sharedSettings.equipmentMeasurement = state.equipmentMeasurement - state.destination = .flaggedMeasurementsList(.init(sharedSettings: state.$sharedSettings)) + state.destination = .flaggedMeasurementsList(.init( + sharedSettings: state.$sharedSettings + )) return .none case .onAppear: @@ -224,7 +226,7 @@ public struct EquipmentMeasurementForm { } } -fileprivate extension Store where State == EquipmentMeasurementForm.State { +extension Store where State == EquipmentMeasurementForm.State { func prompt( field: EquipmentMeasurementForm.State.Field diff --git a/Sources/PressureEstimationsFeature/EquipmentSettingsForm.swift b/Sources/PressureEstimationsFeature/EquipmentSettingsForm.swift index 458e01e..c2d90af 100644 --- a/Sources/PressureEstimationsFeature/EquipmentSettingsForm.swift +++ b/Sources/PressureEstimationsFeature/EquipmentSettingsForm.swift @@ -9,7 +9,7 @@ import SwiftUI public struct EquipmentSettingsForm { @CasePathable - public enum InfoView { + public enum InfoView: CaseIterable { case capacities case manufacturersIncludedFilterPressureDrop case ratedStaticPressures @@ -95,7 +95,7 @@ public struct EquipmentSettingsForm { return .none case .binding(\.minStaticPressure): - state.sharedSettings.handleStaticPressure(\.maximum, state.minStaticPressure) + state.sharedSettings.handleStaticPressure(\.minimum, state.minStaticPressure) return .none case .binding(\.ratedStaticPressure): @@ -329,7 +329,7 @@ fileprivate struct BudgetFlagViewStyle: FlaggedViewStyle { } } -fileprivate extension InfoViewFeature.State { +extension InfoViewFeature.State { init(view: EquipmentSettingsForm.InfoView) { switch view { case .capacities: diff --git a/Tests/PressureEstimationsFeatureTests/EquipmentMeasurementFormTests.swift b/Tests/PressureEstimationsFeatureTests/EquipmentMeasurementFormTests.swift new file mode 100644 index 0000000..d8e6f53 --- /dev/null +++ b/Tests/PressureEstimationsFeatureTests/EquipmentMeasurementFormTests.swift @@ -0,0 +1,138 @@ +import ComposableArchitecture +@testable import PressureEstimationsFeature +import SharedModels +import Testing +import XCTest + +struct EquipmentMeasurementFormStateTests { + + @Test( + "Validatons", + .tags(.equipmentMeasurementForm) + ) + func validations() async throws { + var state = EquipmentMeasurementForm.State( + sharedSettings: Shared(SharedPressureEstimationState()) + ) + + #expect(state.isValid == false) + + state.measurements.airflow = 1200 + state.measurements.returnPlenumPressure = 0.2 + state.measurements.supplyPlenumPressure = 0.3 + + #expect(state.isValid == true) + + state.equipmentType = .furnaceAndCoil + #expect(state.isValid == false) + + state.measurements.postFilterPressure = 0.5 + state.measurements.coilPressure = 0.3 + #expect(state.isValid == true) + + } + + @Test( + "Measurement initialization with EquipmentMeasurement", + .tags(.equipmentMeasurementForm), + arguments: [ + EquipmentMeasurement.mock(type: .airHandler), + EquipmentMeasurement.mock(type: .furnaceAndCoil), + ] + ) + func measurementConversions(equipmentMeasurement: EquipmentMeasurement) { + let measurement = EquipmentMeasurementForm.State.Measurements( + equipmentMeasurement: equipmentMeasurement + ) + #expect(measurement.equipmentMeasurement(type: equipmentMeasurement.equipmentType) == equipmentMeasurement) + } + + @Test( + "Measurement to EquipmentMeasurement", + .tags(.equipmentMeasurementForm) + ) + func measurementToEquipmentMeasurement() { + let measurement = EquipmentMeasurementForm.State.Measurements() + var equipmentMeasurement = EquipmentMeasurement.airHandler( + EquipmentMeasurement.AirHandler( + airflow: 0, + manufacturersIncludedFilterPressureDrop: 0.1, + returnPlenumPressure: 0, + postFilterPressure: 0, + postCoilPressure: 0, + supplyPlenumPressure: 0 + ) + ) + #expect(measurement.equipmentMeasurement(type: .airHandler) == equipmentMeasurement) + + equipmentMeasurement = .furnaceAndCoil( + EquipmentMeasurement.FurnaceAndCoil( + airflow: 0.0, + manufacturersIncludedFilterPressureDrop: 0, + returnPlenumPressure: 0, + postFilterPressure: 0, + preCoilPressure: 0, + supplyPlenumPressure: 0 + ) + ) + #expect(measurement.equipmentMeasurement(type: .furnaceAndCoil) == equipmentMeasurement) + } + +// @Test() +// func promptAndLabel() { +// let store = Store( +// initialState: EquipmentMeasurementForm.State( +// sharedSettings: Shared(SharedPressureEstimationState()) +// ), +// reducer: EquipmentMeasurementForm.init +// ) +// +// } + + +} + +final class EquipmentMeasurementFormReducerTests: XCTestCase { + + @MainActor + func testReducer() async throws { + let store = TestStore( + initialState: EquipmentMeasurementForm.State( + sharedSettings: Shared(SharedPressureEstimationState( + equipmentMeasurement: .mock(type: .airHandler) + )) + ), + reducer: EquipmentMeasurementForm.init + ) + + await store.send(.view(.onAppear)) { + $0.measurements = .init(equipmentMeasurement: .mock(type: .airHandler)) + } + await store.send(.binding(.set(\.focusedField, .airflow))) { + $0.focusedField = .airflow + } + await store.send(.view(.nextButtonTapped)) { + $0.destination = .flaggedMeasurementsList(.init( + sharedSettings: Shared(SharedPressureEstimationState( + equipmentMeasurement: .mock(type: .airHandler) + )) + )) + } + await store.send(.destination(.dismiss)) { + $0.destination = nil + } + await store.send(.view(.resetButtonTapped)) { + $0.measurements = .init() + } + + store.exhaustivity = .off + await store.send(.view(.infoButtonTapped)) + + await store.finish() + } + +} + +extension Tag { + @Tag static var equipmentMeasurementForm: Self +} diff --git a/Tests/PressureEstimationsFeatureTests/EquipmentSettingsFormTests.swift b/Tests/PressureEstimationsFeatureTests/EquipmentSettingsFormTests.swift index 5f6b33f..60a915e 100644 --- a/Tests/PressureEstimationsFeatureTests/EquipmentSettingsFormTests.swift +++ b/Tests/PressureEstimationsFeatureTests/EquipmentSettingsFormTests.swift @@ -27,11 +27,86 @@ struct EquipmentSettingsFormStateTests { #expect(sharedSettings.equipmentMetadata.ratedStaticPressures.rated == 0) } } + + struct ValidationContainer { + let state: EquipmentSettingsForm.State + let expectsValid: Bool + } + + @Test( + "Validations", + .tags(.equipmentSettingsForm), + arguments: [ + ValidationContainer( + state: .init(sharedSettings: Shared(SharedPressureEstimationState())), + expectsValid: true + ), + ValidationContainer( + state: .init( + equipmentType: .furnaceAndCoil, + sharedSettings: Shared(SharedPressureEstimationState()) + ), + expectsValid: false + ) + ] + ) + func validation(container: ValidationContainer) { + #expect(container.state.isValid == container.expectsValid) + } } final class EquipmentSettingsFormTests: XCTestCase { + @MainActor + func testStaticPressureBindings() async throws { + let store = TestStore( + initialState: EquipmentSettingsForm.State(sharedSettings: Shared(SharedPressureEstimationState())) + ) { + EquipmentSettingsForm() + } + + await store.send(.binding(.set(\.maxStaticPressure, nil))) { + $0.maxStaticPressure = nil + $0.sharedSettings.ratedStaticPressures.maximum = 0 + } + + await store.send(.binding(.set(\.minStaticPressure, nil))) { + $0.minStaticPressure = nil + $0.sharedSettings.ratedStaticPressures.minimum = 0 + } + + await store.send(.binding(.set(\.ratedStaticPressure, nil))) { + $0.ratedStaticPressure = nil + $0.sharedSettings.ratedStaticPressures.rated = 0 + } + } + @MainActor + func testViewActions() async throws { + let store = TestStore( + initialState: EquipmentSettingsForm.State( + equipmentType: .furnaceAndCoil, + sharedSettings: Shared(SharedPressureEstimationState(heatingCapacity: 20_000)) + ) + ) { + EquipmentSettingsForm() + } + + await store.send(.view(.resetButtonTapped)) { + $0.sharedSettings.heatingCapacity = nil + } + await store.send(.view(.submitField)) + + for infoView in EquipmentSettingsForm.InfoView.allCases { + await store.send(.view(.infoButtonTapped(infoView))) { + $0.destination = .infoView(.init(view: infoView)) + } + await store.send(.destination(.dismiss)) { + $0.destination = nil + } + } + + } } extension Tag {