diff --git a/NativeAppTemplateTests/Data/ViewModels/TabViewModelTest.swift b/NativeAppTemplateTests/Data/ViewModels/TabViewModelTest.swift new file mode 100644 index 0000000..8b611a7 --- /dev/null +++ b/NativeAppTemplateTests/Data/ViewModels/TabViewModelTest.swift @@ -0,0 +1,35 @@ +// +// TabViewModelTest.swift +// NativeAppTemplate +// + +import Foundation +@testable import NativeAppTemplate +import Testing + +@MainActor +@Suite +struct TabViewModelTest { + @Test + func initialState() { + let viewModel = TabViewModel() + + #expect(viewModel.selectedTab == .shops) + for tab in MainTab.allCases { + #expect(viewModel.showingDetailView[tab] == false) + } + } + + @Test + func showingDetailView() { + let viewModel = TabViewModel() + + viewModel.showingDetailView[.shops] = true + #expect(viewModel.showingDetailView[.shops] == true) + #expect(viewModel.showingDetailView[.scan] == false) + #expect(viewModel.showingDetailView[.settings] == false) + + viewModel.showingDetailView[.shops] = false + #expect(viewModel.showingDetailView[.shops] == false) + } +} diff --git a/NativeAppTemplateTests/Extensions/StringExtensionsTest.swift b/NativeAppTemplateTests/Extensions/StringExtensionsTest.swift new file mode 100644 index 0000000..adfcf1b --- /dev/null +++ b/NativeAppTemplateTests/Extensions/StringExtensionsTest.swift @@ -0,0 +1,38 @@ +// +// StringExtensionsTest.swift +// NativeAppTemplate +// + +import CoreGraphics +@testable import NativeAppTemplate +import Testing + +struct StringExtensionsTest { + @Test(arguments: [ + ("hello123", true), + ("ABC", true), + ("abc", true), + ("123", true), + ("Hello World", false), + ("hello!", false), + ("hello@world", false), + ("", false) + ]) + func isAlphanumeric(input: String, expected: Bool) { + #expect(input.isAlphanumeric() == expected) + } + + @Test + func isAlphanumericIgnoringDiacritics() { + #expect("hello123".isAlphanumeric(ignoreDiacritics: true) == true) + #expect("ABC123".isAlphanumeric(ignoreDiacritics: true) == true) + #expect("hello world".isAlphanumeric(ignoreDiacritics: true) == false) + #expect("".isAlphanumeric(ignoreDiacritics: true) == false) + } + + @Test + func imageGeneration() { + let image = "A".image(size: CGSize(width: 50, height: 50)) + #expect(image != nil) + } +} diff --git a/NativeAppTemplateTests/Models/ItemTagStateTest.swift b/NativeAppTemplateTests/Models/ItemTagStateTest.swift new file mode 100644 index 0000000..9ecc864 --- /dev/null +++ b/NativeAppTemplateTests/Models/ItemTagStateTest.swift @@ -0,0 +1,21 @@ +// +// ItemTagStateTest.swift +// NativeAppTemplate +// + +@testable import NativeAppTemplate +import Testing + +struct ItemTagStateTest { + @Test + func initFromValidStrings() { + #expect(ItemTagState(string: "idled") == .idled) + #expect(ItemTagState(string: "completed") == .completed) + } + + @Test + func initFromUnknownStringDefaultsToIdled() { + #expect(ItemTagState(string: "unknown") == .idled) + #expect(ItemTagState(string: "") == .idled) + } +} diff --git a/NativeAppTemplateTests/Models/ItemTagTypeTest.swift b/NativeAppTemplateTests/Models/ItemTagTypeTest.swift new file mode 100644 index 0000000..a367d44 --- /dev/null +++ b/NativeAppTemplateTests/Models/ItemTagTypeTest.swift @@ -0,0 +1,27 @@ +// +// ItemTagTypeTest.swift +// NativeAppTemplate +// + +@testable import NativeAppTemplate +import Testing + +struct ItemTagTypeTest { + @Test + func initFromValidStrings() { + #expect(ItemTagType(string: "server") == .server) + #expect(ItemTagType(string: "customer") == .customer) + } + + @Test + func initFromUnknownStringDefaultsToServer() { + #expect(ItemTagType(string: "unknown") == .server) + #expect(ItemTagType(string: "") == .server) + } + + @Test + func toJsonRoundtrip() { + #expect(ItemTagType(string: ItemTagType.server.toJson()) == .server) + #expect(ItemTagType(string: ItemTagType.customer.toJson()) == .customer) + } +} diff --git a/NativeAppTemplateTests/Models/ScanStateTest.swift b/NativeAppTemplateTests/Models/ScanStateTest.swift new file mode 100644 index 0000000..bac41f8 --- /dev/null +++ b/NativeAppTemplateTests/Models/ScanStateTest.swift @@ -0,0 +1,27 @@ +// +// ScanStateTest.swift +// NativeAppTemplate +// + +@testable import NativeAppTemplate +import Testing + +struct ScanStateTest { + @Test + func initFromValidStrings() { + #expect(ScanState(string: "unscanned") == .unscanned) + #expect(ScanState(string: "scanned") == .scanned) + } + + @Test + func initFromUnknownStringDefaultsToUnscanned() { + #expect(ScanState(string: "unknown") == .unscanned) + #expect(ScanState(string: "") == .unscanned) + } + + @Test + func toJsonRoundtrip() { + #expect(ScanState(string: ScanState.unscanned.toJson()) == .unscanned) + #expect(ScanState(string: ScanState.scanned.toJson()) == .scanned) + } +} diff --git a/NativeAppTemplateTests/Utilities/MessageBusTest.swift b/NativeAppTemplateTests/Utilities/MessageBusTest.swift new file mode 100644 index 0000000..649c2d5 --- /dev/null +++ b/NativeAppTemplateTests/Utilities/MessageBusTest.swift @@ -0,0 +1,81 @@ +// +// MessageBusTest.swift +// NativeAppTemplate +// + +@testable import NativeAppTemplate +import Testing + +@MainActor +@Suite +struct MessageBusTest { + @Test + func initialState() { + let bus = MessageBus() + + #expect(bus.currentMessage == nil) + #expect(bus.messageVisible == false) + } + + @Test + func postMessageSetsCurrentMessage() { + let bus = MessageBus() + + bus.post(message: Message(level: .success, message: "Done")) + + #expect(bus.currentMessage != nil) + #expect(bus.currentMessage?.message == "Done") + #expect(bus.currentMessage?.level == .success) + #expect(bus.messageVisible == true) + } + + @Test + func postErrorMessage() { + let bus = MessageBus() + + bus.post(message: Message(level: .error, message: "Failed", autoDismiss: false)) + + #expect(bus.currentMessage?.level == .error) + #expect(bus.currentMessage?.message == "Failed") + #expect(bus.currentMessage?.autoDismiss == false) + #expect(bus.messageVisible == true) + } + + @Test + func dismiss() { + let bus = MessageBus() + + bus.post(message: Message(level: .success, message: "Done")) + #expect(bus.messageVisible == true) + + bus.dismiss() + #expect(bus.messageVisible == false) + } + + @Test + func postReplacesExistingMessage() { + let bus = MessageBus() + + bus.post(message: Message(level: .success, message: "First")) + bus.post(message: Message(level: .error, message: "Second")) + + #expect(bus.currentMessage?.message == "Second") + #expect(bus.currentMessage?.level == .error) + } + + @Test + func snackbarState() { + let message = Message(level: .error, message: "Error occurred") + let snackbarState = message.snackbarState + + #expect(snackbarState.status == .error) + #expect(snackbarState.message == "Error occurred") + } + + @Test + func messageLevelSnackbarStatus() { + #expect(Message.Level.error.snackbarStatus == .error) + #expect(Message.Level.warning.snackbarStatus == .warning) + #expect(Message.Level.success.snackbarStatus == .success) + } +} diff --git a/NativeAppTemplateTests/Utilities/UtilityTest.swift b/NativeAppTemplateTests/Utilities/UtilityTest.swift new file mode 100644 index 0000000..61e123f --- /dev/null +++ b/NativeAppTemplateTests/Utilities/UtilityTest.swift @@ -0,0 +1,53 @@ +// +// UtilityTest.swift +// NativeAppTemplate +// + +import Foundation +@testable import NativeAppTemplate +import Testing + +struct UtilityTest { + @Test + func scanUrlContainsExpectedParams() { + let url = Utility.scanUrl(itemTagId: "abc-123", itemTagType: "server") + + #expect(url.absoluteString.contains("item_tag_id=abc-123")) + #expect(url.absoluteString.contains("type=server")) + } + + @Test + func scanUrlCustomerType() { + let url = Utility.scanUrl(itemTagId: "xyz-456", itemTagType: "customer") + + #expect(url.absoluteString.contains("item_tag_id=xyz-456")) + #expect(url.absoluteString.contains("type=customer")) + } + + @Test(arguments: [ + ("", true), + (" ", true), + ("\n", true), + (" \t\n ", true), + ("hello", false), + (" hello ", false) + ]) + func isBlank(text: String, expected: Bool) { + #expect(Utility.isBlank(text) == expected) + } + + @Test(arguments: [ + ("test@example.com", true), + ("user.name+tag@domain.co", true), + ("user@domain.com", true), + ("", false), + ("notanemail", false), + ("@domain.com", false), + ("user@", false), + ("user@.com", false) + ]) + func validateEmail(email: String, expected: Bool) { + #expect(Utility.validateEmail(email) == expected) + } + +}