test(MiniProject): extract RunnerCore library with Swift Testing suite

Split UI-free logic into a RunnerCore swift_library and cover it with a
swift_test suite using the Swift Testing library (import Testing / @Test /
#expect), matching Tests/m323Tests. Runs via `bazel test`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cediackermann 2026-07-06 08:47:33 +02:00
parent b1968074b6
commit 13876d51c2
No known key found for this signature in database
10 changed files with 1023 additions and 319 deletions

View file

@ -1,11 +1,30 @@
load("@rules_swift//swift:swift.bzl", "swift_binary")
load("@rules_swift//swift:swift.bzl", "swift_binary", "swift_library", "swift_test")
# Pure, UI-free logic (models, parsing, transforms, formatting). Kept out of the
# binary so it can be exercised by //m323/Sources/MiniProject:RunnerCoreTests.
swift_library(
name = "RunnerCore",
srcs = ["RunnerCore.swift"],
module_name = "RunnerCore",
visibility = ["//visibility:public"],
)
swift_binary(
name = "StadtRundlauf",
srcs = ["main.swift"],
data = glob(["data/*.txt"]),
visibility = ["//visibility:public"],
deps = ["@swifttui//:SwiftTUI"],
deps = [
":RunnerCore",
"@swifttui//:SwiftTUI",
],
)
swift_test(
name = "RunnerCoreTests",
srcs = ["RunnerCoreTests.swift"],
visibility = ["//visibility:public"],
deps = [":RunnerCore"],
)
# BEGIN GENERATED XCODEPROJ
@ -33,6 +52,7 @@ xcodeproj(
tags = ["manual"],
extra_files = [":xcodeproj_extra_files"],
top_level_targets = [
"//m323/Sources/MiniProject:RunnerCoreTests",
"//m323/Sources/MiniProject:StadtRundlauf",
],
)

View file

@ -176,11 +176,19 @@
CreatedOnToolsVersion = 26.6.0;
LastSwiftMigration = 9999;
};
0100FAB81B6F000000000001 = {
00001E1FC9CF000000000001 = {
CreatedOnToolsVersion = 26.6.0;
LastSwiftMigration = 9999;
};
00004EB553A7000000000001 = {
010021D7AEE9000000000001 = {
CreatedOnToolsVersion = 26.6.0;
LastSwiftMigration = 9999;
};
0300FAB81B6F000000000001 = {
CreatedOnToolsVersion = 26.6.0;
LastSwiftMigration = 9999;
};
02004EB553A7000000000001 = {
CreatedOnToolsVersion = 26.6.0;
LastSwiftMigration = 9999;
};
@ -192,11 +200,13 @@
);
targets = (
FF0100000000000000000001 /* BazelDependencies */,
0100FAB81B6F000000000001 /* StadtRundlauf */,
00004EB553A7000000000001 /* SwiftTUI */,
00001E1FC9CF000000000001 /* RunnerCore */,
010021D7AEE9000000000001 /* RunnerCoreTests */,
0300FAB81B6F000000000001 /* StadtRundlauf */,
02004EB553A7000000000001 /* SwiftTUI */,
);
};
00004EB553A7000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */ = {
00001E1FC9CF000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
@ -212,84 +222,246 @@
shellScript = "set -euo pipefail\n\nif [[ \"$ACTION\" == \"indexbuild\" ]]; then\n cd \"$SRCROOT\"\n\n \"$BAZEL_INTEGRATION_DIR/generate_index_build_bazel_dependencies.sh\"\nelse\n \"$BAZEL_INTEGRATION_DIR/copy_outputs.sh\" \\\n \"_BazelForcedCompile_.swift\" \\\n \"\"\nfi\n";
showEnvVarsInLog = 0;
};
00004EB553A7000000000006 /* Sources */ = {
00001E1FC9CF000000000006 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
00FFC950564A0A8E85DE76AA /* Control.swift in Sources */,
00FFC927145F56EA91D8C9F9 /* Window.swift in Sources */,
00FF769EE4F24E03387EE327 /* Control+logTree.swift in Sources */,
00FF15120A8D075045D0C31A /* Node+logTree.swift in Sources */,
00FF02DFBDB02EF7CA6730AD /* log.swift in Sources */,
00FF5E51E93E85114A81C2ED /* AttributeScopes+SwiftTUIAttributes.swift in Sources */,
00FF9443A13020538EDF8602 /* Cell.swift in Sources */,
00FF29699AA621079339AEA2 /* CellAttributes.swift in Sources */,
00FF28471707BD8316B43410 /* Color.swift in Sources */,
00FFC77584E23F3984779346 /* Edges.swift in Sources */,
00FF38B4059491987FAEE965 /* Extended.swift in Sources */,
00FFDC2481C8A9ED7403DE2C /* Position.swift in Sources */,
00FF69CEE00F16C55B995EA3 /* Rect.swift in Sources */,
00FF40BBB288C62260CA76C3 /* EscapeSequence.swift in Sources */,
00FF79AAF9921EE12F892356 /* Layer.swift in Sources */,
00FF3A4B43C80D488C7CE32B /* LayerDrawing.swift in Sources */,
00FFF2E0DDE16A7D1010746B /* Renderer.swift in Sources */,
00FFDFD37AE54401B53A5ABB /* Size.swift in Sources */,
00FFB7DC9A3293ECE8393A58 /* Binding.swift in Sources */,
00FF4A4ABC004B5FF5637D01 /* Environment.swift in Sources */,
00FF3B45C9889ED370565846 /* ObservedObject.swift in Sources */,
00FF2C946200B58812B667DF /* State.swift in Sources */,
00FFEE3805EB06CFC8FC03C7 /* View+Environment.swift in Sources */,
00FF76C198B892A242BACBA0 /* View+ObservableObject.swift in Sources */,
00FF33C3B2D6D0317F653F20 /* View+State.swift in Sources */,
00FF49436AF208504407BD30 /* ASCII.swift in Sources */,
00FFF11402FCE9EA7A96512F /* Application.swift in Sources */,
00FF1F9002855C61CF31D72C /* ArrowKeyParser.swift in Sources */,
00FF1BC72723E836422B53B6 /* SwiftTUI.swift in Sources */,
00FF6E0FF588278BC1C0E96E /* ComposedView.swift in Sources */,
00FFC7BA845C5AB46EEDD9EC /* GenericView.swift in Sources */,
00FF24113C0B99C3349F0761 /* LayoutRootView.swift in Sources */,
00FF8259DABBDE007D9CA96C /* ModifierView.swift in Sources */,
00FFA88328D15EA01534CBB6 /* Node.swift in Sources */,
00FFB9C9BAB730C1E9019D6D /* PrimitiveView.swift in Sources */,
00FF0DE18E6C3150EE967582 /* View.swift in Sources */,
00FF0428EFF8BC4844DFEEF5 /* Weak.swift in Sources */,
00FFEE5BFF62FA2C9CE8512D /* WeakSet.swift in Sources */,
00FF7FEDD08A068D8D066266 /* Button.swift in Sources */,
00FF89E95841426E895D81E5 /* Color+View.swift in Sources */,
00FF65FFCD86BF306BEC3471 /* Divider.swift in Sources */,
00FFAC2EE02A2748301EB053 /* GeometryReader.swift in Sources */,
00FFF57F463FD5B6941F2333 /* ScrollView.swift in Sources */,
00FFCEF1BD7F380C94FAADB0 /* Spacer.swift in Sources */,
00FF23D86E413506C6F7DB25 /* Text.swift in Sources */,
00FF45B8E101B2B215011288 /* TextField.swift in Sources */,
00FFE75BB68A3EF17D60E39C /* EmptyView.swift in Sources */,
00FFAE6A70F1E1714BD84C61 /* ForEach.swift in Sources */,
00FFC6099114A3970F594B5A /* Group.swift in Sources */,
00FF86BDBAB1FB01FC69713C /* Background.swift in Sources */,
00FF0E0C217BCA513AA25E42 /* Bold.swift in Sources */,
00FF1F7CE9DEE5E71B7FD162 /* Border.swift in Sources */,
00FF17E30E5E434F1A61B03E /* FixedFrame.swift in Sources */,
00FF2570965BBE7BAABB7C8F /* FlexibleFrame.swift in Sources */,
00FF2E046DCFA53B787E8B14 /* ForegroundColor.swift in Sources */,
00FF159F585DA1FE891AC212 /* Italic.swift in Sources */,
00FFFD7F86C6332ACFE8E09A /* OnAppear.swift in Sources */,
00FF4600097791854D5254C8 /* Padding.swift in Sources */,
00FF7EBE80C2D2F703193AE2 /* SetEnvironment.swift in Sources */,
00FF187F7C193AE2DC5C0569 /* Strikethrough.swift in Sources */,
00FF377E17D813E1DF17B011 /* Underline.swift in Sources */,
00FFD84E8471C8E5126FC9E0 /* Optional+View.swift in Sources */,
00FF8C1E18A733FD0EE6B012 /* Alignment.swift in Sources */,
00FF0AA743B1E02D724F5F8C /* Axis.swift in Sources */,
00FF3907B1397417683BA7FC /* HStack.swift in Sources */,
00FF814531DF6F008282E112 /* VStack.swift in Sources */,
00FF5528E4594080E339FE5E /* ZStack.swift in Sources */,
00FFB8584ED0017DB11DE731 /* TupleView.swift in Sources */,
00FFB51099CAC91D5F78F022 /* ViewBuilder.swift in Sources */,
00FF8FA09DB2BD499064AC64 /* _ConditionalView.swift in Sources */,
00FF1E5231001920CAE02B34 /* RunnerCore.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
00004EB553A7000000000100 /* Debug */ = {
00001E1FC9CF000000000100 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = arm64;
BAZEL_LABEL = "@@//m323/Sources/MiniProject:RunnerCore";
BAZEL_OUTPUTS_PRODUCT = "bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/libRunnerCore.a";
BAZEL_OUTPUTS_PRODUCT_BASENAME = libRunnerCore.a;
BAZEL_PACKAGE_BIN_DIR = "bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject";
BAZEL_TARGET_ID = "@@//m323/Sources/MiniProject:RunnerCore darwin_arm64-dbg-ST-9a5aec5712f9";
COMPILE_TARGET_NAME = RunnerCore;
MACOSX_DEPLOYMENT_TARGET = 26.5;
OTHER_SWIFT_FLAGS = "-Xcc -working-directory -Xcc $(PROJECT_DIR) -working-directory $(PROJECT_DIR) -enforce-exclusivity=checked -emit-const-values-path bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/RunnerCore_objs/RunnerCore.swift.swiftconstvalues -DDEBUG -Onone -Xfrontend -internalize-at-link -enable-testing -disable-sandbox -file-compilation-dir . -Xcc -iquote -Xcc $(PROJECT_DIR) -Xcc -iquote -Xcc $(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin -Xfrontend -disable-clang-spi -enable-experimental-feature AccessLevelOnImport -static -Xcc -O0 -Xcc -DDEBUG=1 -Xcc -fstack-protector -Xcc -fstack-protector-all -Xfrontend -checked-async-objc-bridging=on";
PRODUCT_MODULE_NAME = RunnerCore;
PRODUCT_NAME = RunnerCore;
SDKROOT = macosx;
SUPPORTED_PLATFORMS = macosx;
SWIFT_ENABLE_EMIT_CONST_VALUES = NO;
TARGET_NAME = RunnerCore;
};
name = Debug;
};
00001E1FC9CF000000000002 /* Build configuration list for PBXNativeTarget "RunnerCore" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00001E1FC9CF000000000100 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
00001E1FC9CF0000000000FF /* libRunnerCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRunnerCore.a; sourceTree = BUILT_PRODUCTS_DIR; };
00001E1FC9CF000000000001 /* RunnerCore */ = {
isa = PBXNativeTarget;
buildConfigurationList = 00001E1FC9CF000000000002 /* Build configuration list for PBXNativeTarget "RunnerCore" */;
buildPhases = (
00001E1FC9CF000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */,
00001E1FC9CF000000000006 /* Sources */,
);
buildRules = (
);
dependencies = (
00021E1FC9CFFF0001000000 /* PBXTargetDependency */,
);
name = RunnerCore;
productName = RunnerCore;
productType = "com.apple.product-type.library.static";
};
010021D7AEE9000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)",
);
name = "Copy Bazel Outputs / Generate Bazel Dependencies (Index Build)";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -euo pipefail\n\nif [[ \"$ACTION\" == \"indexbuild\" ]]; then\n cd \"$SRCROOT\"\n\n \"$BAZEL_INTEGRATION_DIR/generate_index_build_bazel_dependencies.sh\"\nelse\n \"$BAZEL_INTEGRATION_DIR/copy_outputs.sh\" \\\n \"_BazelForcedCompile_.swift\" \\\n \"$BAZEL_INTEGRATION_DIR/xctest.exclude.rsynclist\"\nfi\n";
showEnvVarsInLog = 0;
};
010021D7AEE9000000000005 /* Create Link Dependencies */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(LINK_PARAMS_FILE)",
);
name = "Create Link Dependencies";
outputPaths = (
"$(DERIVED_FILE_DIR)/link.params",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -euo pipefail\n\nif [[ \"${ENABLE_PREVIEWS:-}\" == \"YES\" ]]; then\nperl -pe 's/\\$(\\()?([a-zA-Z_]\\w*)(?(1)\\))/$ENV{$2}/g' \\\n \"$SCRIPT_INPUT_FILE_0\" > \"$SCRIPT_OUTPUT_FILE_0\"\nelse\n touch \"$SCRIPT_OUTPUT_FILE_0\"\nfi\n";
showEnvVarsInLog = 0;
};
010021D7AEE9000000000006 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
01FF0A9B8F2DD54D7DC622F9 /* RunnerCoreTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
010021D7AEE9000000000100 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = arm64;
BAZEL_LABEL = "@@//m323/Sources/MiniProject:RunnerCoreTests";
BAZEL_OUTPUTS_PRODUCT = "bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/RunnerCoreTests.xctest";
BAZEL_OUTPUTS_PRODUCT_BASENAME = RunnerCoreTests.xctest;
BAZEL_PACKAGE_BIN_DIR = "bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject";
BAZEL_TARGET_ID = "@@//m323/Sources/MiniProject:RunnerCoreTests darwin_arm64-dbg-ST-9a5aec5712f9";
COMPILE_TARGET_NAME = RunnerCoreTests;
LINK_PARAMS_FILE = "$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/RunnerCoreTests.rules_xcodeproj.link.params";
MACOSX_DEPLOYMENT_TARGET = 26.5;
OTHER_LDFLAGS = "@$(DERIVED_FILE_DIR)/link.params";
OTHER_SWIFT_FLAGS = "-Xcc -working-directory -Xcc $(PROJECT_DIR) -working-directory $(PROJECT_DIR) -enforce-exclusivity=checked -emit-const-values-path bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/RunnerCoreTests_objs/RunnerCoreTests.swift.swiftconstvalues -DDEBUG -Onone -Xfrontend -internalize-at-link -enable-testing -disable-sandbox -F$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/Library/Frameworks -I$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/usr/lib -file-compilation-dir . -I$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject -plugin-path __BAZEL_SWIFT_TOOLCHAIN_PATH__/usr/lib/swift/host/plugins/testing -Xcc -iquote -Xcc $(PROJECT_DIR) -Xcc -iquote -Xcc $(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin -Xfrontend -disable-clang-spi -enable-experimental-feature AccessLevelOnImport -enable-testing -Xcc -O0 -Xcc -DDEBUG=1 -Xcc -fstack-protector -Xcc -fstack-protector-all -Xfrontend -checked-async-objc-bridging=on";
PRODUCT_MODULE_NAME = m323_Sources_MiniProject_RunnerCoreTests;
PRODUCT_NAME = RunnerCoreTests;
SDKROOT = macosx;
SUPPORTED_PLATFORMS = macosx;
SWIFT_ENABLE_EMIT_CONST_VALUES = NO;
TARGET_NAME = RunnerCoreTests;
};
name = Debug;
};
010021D7AEE9000000000002 /* Build configuration list for PBXNativeTarget "RunnerCoreTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
010021D7AEE9000000000100 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
010021D7AEE90000000000FF /* RunnerCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
010021D7AEE9000000000001 /* RunnerCoreTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 010021D7AEE9000000000002 /* Build configuration list for PBXNativeTarget "RunnerCoreTests" */;
buildPhases = (
010021D7AEE9000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */,
010021D7AEE9000000000005 /* Create Link Dependencies */,
010021D7AEE9000000000006 /* Sources */,
);
buildRules = (
);
dependencies = (
010221D7AEE9FF0001000000 /* PBXTargetDependency */,
);
name = RunnerCoreTests;
productName = RunnerCoreTests;
productReference = 010021D7AEE90000000000FF /* RunnerCoreTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
02004EB553A7000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Bazel Outputs / Generate Bazel Dependencies (Index Build)";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -euo pipefail\n\nif [[ \"$ACTION\" == \"indexbuild\" ]]; then\n cd \"$SRCROOT\"\n\n \"$BAZEL_INTEGRATION_DIR/generate_index_build_bazel_dependencies.sh\"\nelse\n \"$BAZEL_INTEGRATION_DIR/copy_outputs.sh\" \\\n \"_BazelForcedCompile_.swift\" \\\n \"\"\nfi\n";
showEnvVarsInLog = 0;
};
02004EB553A7000000000006 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
02FFC950564A0A8E85DE76AA /* Control.swift in Sources */,
02FFC927145F56EA91D8C9F9 /* Window.swift in Sources */,
02FF769EE4F24E03387EE327 /* Control+logTree.swift in Sources */,
02FF15120A8D075045D0C31A /* Node+logTree.swift in Sources */,
02FF02DFBDB02EF7CA6730AD /* log.swift in Sources */,
02FF5E51E93E85114A81C2ED /* AttributeScopes+SwiftTUIAttributes.swift in Sources */,
02FF9443A13020538EDF8602 /* Cell.swift in Sources */,
02FF29699AA621079339AEA2 /* CellAttributes.swift in Sources */,
02FF28471707BD8316B43410 /* Color.swift in Sources */,
02FFC77584E23F3984779346 /* Edges.swift in Sources */,
02FF38B4059491987FAEE965 /* Extended.swift in Sources */,
02FFDC2481C8A9ED7403DE2C /* Position.swift in Sources */,
02FF69CEE00F16C55B995EA3 /* Rect.swift in Sources */,
02FF40BBB288C62260CA76C3 /* EscapeSequence.swift in Sources */,
02FF79AAF9921EE12F892356 /* Layer.swift in Sources */,
02FF3A4B43C80D488C7CE32B /* LayerDrawing.swift in Sources */,
02FFF2E0DDE16A7D1010746B /* Renderer.swift in Sources */,
02FFDFD37AE54401B53A5ABB /* Size.swift in Sources */,
02FFB7DC9A3293ECE8393A58 /* Binding.swift in Sources */,
02FF4A4ABC004B5FF5637D01 /* Environment.swift in Sources */,
02FF3B45C9889ED370565846 /* ObservedObject.swift in Sources */,
02FF2C946200B58812B667DF /* State.swift in Sources */,
02FFEE3805EB06CFC8FC03C7 /* View+Environment.swift in Sources */,
02FF76C198B892A242BACBA0 /* View+ObservableObject.swift in Sources */,
02FF33C3B2D6D0317F653F20 /* View+State.swift in Sources */,
02FF49436AF208504407BD30 /* ASCII.swift in Sources */,
02FFF11402FCE9EA7A96512F /* Application.swift in Sources */,
02FF1F9002855C61CF31D72C /* ArrowKeyParser.swift in Sources */,
02FF1BC72723E836422B53B6 /* SwiftTUI.swift in Sources */,
02FF6E0FF588278BC1C0E96E /* ComposedView.swift in Sources */,
02FFC7BA845C5AB46EEDD9EC /* GenericView.swift in Sources */,
02FF24113C0B99C3349F0761 /* LayoutRootView.swift in Sources */,
02FF8259DABBDE007D9CA96C /* ModifierView.swift in Sources */,
02FFA88328D15EA01534CBB6 /* Node.swift in Sources */,
02FFB9C9BAB730C1E9019D6D /* PrimitiveView.swift in Sources */,
02FF0DE18E6C3150EE967582 /* View.swift in Sources */,
02FF0428EFF8BC4844DFEEF5 /* Weak.swift in Sources */,
02FFEE5BFF62FA2C9CE8512D /* WeakSet.swift in Sources */,
02FF7FEDD08A068D8D066266 /* Button.swift in Sources */,
02FF89E95841426E895D81E5 /* Color+View.swift in Sources */,
02FF65FFCD86BF306BEC3471 /* Divider.swift in Sources */,
02FFAC2EE02A2748301EB053 /* GeometryReader.swift in Sources */,
02FFF57F463FD5B6941F2333 /* ScrollView.swift in Sources */,
02FFCEF1BD7F380C94FAADB0 /* Spacer.swift in Sources */,
02FF23D86E413506C6F7DB25 /* Text.swift in Sources */,
02FF45B8E101B2B215011288 /* TextField.swift in Sources */,
02FFE75BB68A3EF17D60E39C /* EmptyView.swift in Sources */,
02FFAE6A70F1E1714BD84C61 /* ForEach.swift in Sources */,
02FFC6099114A3970F594B5A /* Group.swift in Sources */,
02FF86BDBAB1FB01FC69713C /* Background.swift in Sources */,
02FF0E0C217BCA513AA25E42 /* Bold.swift in Sources */,
02FF1F7CE9DEE5E71B7FD162 /* Border.swift in Sources */,
02FF17E30E5E434F1A61B03E /* FixedFrame.swift in Sources */,
02FF2570965BBE7BAABB7C8F /* FlexibleFrame.swift in Sources */,
02FF2E046DCFA53B787E8B14 /* ForegroundColor.swift in Sources */,
02FF159F585DA1FE891AC212 /* Italic.swift in Sources */,
02FFFD7F86C6332ACFE8E09A /* OnAppear.swift in Sources */,
02FF4600097791854D5254C8 /* Padding.swift in Sources */,
02FF7EBE80C2D2F703193AE2 /* SetEnvironment.swift in Sources */,
02FF187F7C193AE2DC5C0569 /* Strikethrough.swift in Sources */,
02FF377E17D813E1DF17B011 /* Underline.swift in Sources */,
02FFD84E8471C8E5126FC9E0 /* Optional+View.swift in Sources */,
02FF8C1E18A733FD0EE6B012 /* Alignment.swift in Sources */,
02FF0AA743B1E02D724F5F8C /* Axis.swift in Sources */,
02FF3907B1397417683BA7FC /* HStack.swift in Sources */,
02FF814531DF6F008282E112 /* VStack.swift in Sources */,
02FF5528E4594080E339FE5E /* ZStack.swift in Sources */,
02FFB8584ED0017DB11DE731 /* TupleView.swift in Sources */,
02FFB51099CAC91D5F78F022 /* ViewBuilder.swift in Sources */,
02FF8FA09DB2BD499064AC64 /* _ConditionalView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
02004EB553A7000000000100 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = arm64;
@ -310,32 +482,32 @@
};
name = Debug;
};
00004EB553A7000000000002 /* Build configuration list for PBXNativeTarget "SwiftTUI" */ = {
02004EB553A7000000000002 /* Build configuration list for PBXNativeTarget "SwiftTUI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00004EB553A7000000000100 /* Debug */,
02004EB553A7000000000100 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
00004EB553A70000000000FF /* libSwiftTUI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSwiftTUI.a; sourceTree = BUILT_PRODUCTS_DIR; };
00004EB553A7000000000001 /* SwiftTUI */ = {
02004EB553A70000000000FF /* libSwiftTUI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSwiftTUI.a; sourceTree = BUILT_PRODUCTS_DIR; };
02004EB553A7000000000001 /* SwiftTUI */ = {
isa = PBXNativeTarget;
buildConfigurationList = 00004EB553A7000000000002 /* Build configuration list for PBXNativeTarget "SwiftTUI" */;
buildConfigurationList = 02004EB553A7000000000002 /* Build configuration list for PBXNativeTarget "SwiftTUI" */;
buildPhases = (
00004EB553A7000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */,
00004EB553A7000000000006 /* Sources */,
02004EB553A7000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */,
02004EB553A7000000000006 /* Sources */,
);
buildRules = (
);
dependencies = (
00024EB553A7FF0001000000 /* PBXTargetDependency */,
02024EB553A7FF0001000000 /* PBXTargetDependency */,
);
name = SwiftTUI;
productName = SwiftTUI;
productType = "com.apple.product-type.library.static";
};
0100FAB81B6F000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */ = {
0300FAB81B6F000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
@ -351,7 +523,7 @@
shellScript = "set -euo pipefail\n\nif [[ \"$ACTION\" == \"indexbuild\" ]]; then\n cd \"$SRCROOT\"\n\n \"$BAZEL_INTEGRATION_DIR/generate_index_build_bazel_dependencies.sh\"\nelse\n \"$BAZEL_INTEGRATION_DIR/copy_outputs.sh\" \\\n \"_BazelForcedCompile_.swift\" \\\n \"\"\nfi\n";
showEnvVarsInLog = 0;
};
0100FAB81B6F000000000005 /* Create Link Dependencies */ = {
0300FAB81B6F000000000005 /* Create Link Dependencies */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -368,15 +540,15 @@
shellScript = "set -euo pipefail\n\nif [[ \"${ENABLE_PREVIEWS:-}\" == \"YES\" ]]; then\nperl -pe 's/\\$(\\()?([a-zA-Z_]\\w*)(?(1)\\))/$ENV{$2}/g' \\\n \"$SCRIPT_INPUT_FILE_0\" > \"$SCRIPT_OUTPUT_FILE_0\"\nelse\n touch \"$SCRIPT_OUTPUT_FILE_0\"\nfi\n";
showEnvVarsInLog = 0;
};
0100FAB81B6F000000000006 /* Sources */ = {
0300FAB81B6F000000000006 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
01FF556AC73989CC680307A3 /* main.swift in Sources */,
03FF556AC73989CC680307A3 /* main.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0100FAB81B6F000000000100 /* Debug */ = {
0300FAB81B6F000000000100 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = arm64;
@ -390,7 +562,7 @@
LINK_PARAMS_FILE = "$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/StadtRundlauf.rules_xcodeproj.link.params";
MACOSX_DEPLOYMENT_TARGET = 26.5;
OTHER_LDFLAGS = "@$(DERIVED_FILE_DIR)/link.params";
OTHER_SWIFT_FLAGS = "-Xcc -working-directory -Xcc $(PROJECT_DIR) -working-directory $(PROJECT_DIR) -enforce-exclusivity=checked -emit-const-values-path bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/StadtRundlauf_objs/main.swift.swiftconstvalues -DDEBUG -Onone -Xfrontend -internalize-at-link -enable-testing -disable-sandbox -file-compilation-dir . -I$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/external/+http_archive+swifttui -Xcc -iquote -Xcc $(PROJECT_DIR) -Xcc -iquote -Xcc $(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin -Xfrontend -disable-clang-spi -enable-experimental-feature AccessLevelOnImport -Xfrontend -entry-point-function-name -Xfrontend m323_Sources_MiniProject_StadtRundlauf_main -Xcc -O0 -Xcc -DDEBUG=1 -Xcc -fstack-protector -Xcc -fstack-protector-all -Xfrontend -checked-async-objc-bridging=on";
OTHER_SWIFT_FLAGS = "-Xcc -working-directory -Xcc $(PROJECT_DIR) -working-directory $(PROJECT_DIR) -enforce-exclusivity=checked -emit-const-values-path bazel-out/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject/StadtRundlauf_objs/main.swift.swiftconstvalues -DDEBUG -Onone -Xfrontend -internalize-at-link -enable-testing -disable-sandbox -file-compilation-dir . -I$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject -I$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/external/+http_archive+swifttui -Xcc -iquote -Xcc $(PROJECT_DIR) -Xcc -iquote -Xcc $(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin -Xfrontend -disable-clang-spi -enable-experimental-feature AccessLevelOnImport -Xfrontend -entry-point-function-name -Xfrontend m323_Sources_MiniProject_StadtRundlauf_main -Xcc -O0 -Xcc -DDEBUG=1 -Xcc -fstack-protector -Xcc -fstack-protector-all -Xfrontend -checked-async-objc-bridging=on";
PRODUCT_MODULE_NAME = m323_Sources_MiniProject_StadtRundlauf;
PRODUCT_NAME = StadtRundlauf;
SDKROOT = macosx;
@ -400,58 +572,84 @@
};
name = Debug;
};
0100FAB81B6F000000000002 /* Build configuration list for PBXNativeTarget "StadtRundlauf" */ = {
0300FAB81B6F000000000002 /* Build configuration list for PBXNativeTarget "StadtRundlauf" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0100FAB81B6F000000000100 /* Debug */,
0300FAB81B6F000000000100 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
0100FAB81B6F0000000000FF /* StadtRundlauf */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = StadtRundlauf; sourceTree = BUILT_PRODUCTS_DIR; };
0100FAB81B6F000000000001 /* StadtRundlauf */ = {
0300FAB81B6F0000000000FF /* StadtRundlauf */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = StadtRundlauf; sourceTree = BUILT_PRODUCTS_DIR; };
0300FAB81B6F000000000001 /* StadtRundlauf */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0100FAB81B6F000000000002 /* Build configuration list for PBXNativeTarget "StadtRundlauf" */;
buildConfigurationList = 0300FAB81B6F000000000002 /* Build configuration list for PBXNativeTarget "StadtRundlauf" */;
buildPhases = (
0100FAB81B6F000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */,
0100FAB81B6F000000000005 /* Create Link Dependencies */,
0100FAB81B6F000000000006 /* Sources */,
0300FAB81B6F000000000003 /* Copy Bazel Outputs / Generate Bazel Dependencies (Index Build) */,
0300FAB81B6F000000000005 /* Create Link Dependencies */,
0300FAB81B6F000000000006 /* Sources */,
);
buildRules = (
);
dependencies = (
0102FAB81B6FFF0001000000 /* PBXTargetDependency */,
0302FAB81B6FFF0001000000 /* PBXTargetDependency */,
);
name = StadtRundlauf;
productName = StadtRundlauf;
productReference = 0100FAB81B6F0000000000FF /* StadtRundlauf */;
productReference = 0300FAB81B6F0000000000FF /* StadtRundlauf */;
productType = "com.apple.product-type.tool";
};
0101FAB81B6FFF0001000000 /* PBXContainerItemProxy */ = {
00011E1FC9CFFF0001000000 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FF0000000000000000000001 /* Project object */;
proxyType = 1;
remoteGlobalIDString = FF0100000000000000000001;
remoteInfo = BazelDependencies;
};
0102FAB81B6FFF0001000000 /* PBXTargetDependency */ = {
00021E1FC9CFFF0001000000 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = BazelDependencies;
target = FF0100000000000000000001 /* BazelDependencies */;
targetProxy = 0101FAB81B6FFF0001000000 /* PBXContainerItemProxy */;
targetProxy = 00011E1FC9CFFF0001000000 /* PBXContainerItemProxy */;
};
00014EB553A7FF0001000000 /* PBXContainerItemProxy */ = {
010121D7AEE9FF0001000000 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FF0000000000000000000001 /* Project object */;
proxyType = 1;
remoteGlobalIDString = FF0100000000000000000001;
remoteInfo = BazelDependencies;
};
00024EB553A7FF0001000000 /* PBXTargetDependency */ = {
010221D7AEE9FF0001000000 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = BazelDependencies;
target = FF0100000000000000000001 /* BazelDependencies */;
targetProxy = 00014EB553A7FF0001000000 /* PBXContainerItemProxy */;
targetProxy = 010121D7AEE9FF0001000000 /* PBXContainerItemProxy */;
};
0301FAB81B6FFF0001000000 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FF0000000000000000000001 /* Project object */;
proxyType = 1;
remoteGlobalIDString = FF0100000000000000000001;
remoteInfo = BazelDependencies;
};
0302FAB81B6FFF0001000000 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = BazelDependencies;
target = FF0100000000000000000001 /* BazelDependencies */;
targetProxy = 0301FAB81B6FFF0001000000 /* PBXContainerItemProxy */;
};
02014EB553A7FF0001000000 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FF0000000000000000000001 /* Project object */;
proxyType = 1;
remoteGlobalIDString = FF0100000000000000000001;
remoteInfo = BazelDependencies;
};
02024EB553A7FF0001000000 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = BazelDependencies;
target = FF0100000000000000000001 /* BazelDependencies */;
targetProxy = 02014EB553A7FF0001000000 /* PBXContainerItemProxy */;
};
FF0000000000000000000003 /* /Users/cediackermann/Projects */ = {
isa = PBXGroup;
@ -477,6 +675,7 @@
sourceTree = "<group>";
};
FE0FE8D7E60C3D79B2E83B9C /* ViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewBuilder.swift; sourceTree = "<group>"; };
FE11C25A4188C21B80521AF7 /* RunnerCore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerCore.swift; sourceTree = "<group>"; };
FE1459FA19AD7E743575B55F /* Sources */ = {
isa = PBXGroup;
children = (
@ -633,6 +832,8 @@
FE4EC1526AFF23247D74D7E5 /* data */,
FE91213EB706159A32807EEC /* BUILD.bazel */,
FE359F43A055950CD2C4031A /* main.swift */,
FE11C25A4188C21B80521AF7 /* RunnerCore.swift */,
FEE8E2B18F627E26CA07D99A /* RunnerCoreTests.swift */,
);
path = MiniProject;
sourceTree = "<group>";
@ -734,6 +935,7 @@
FED14FCCEFFF6DEE187B47AF /* WeakSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakSet.swift; sourceTree = "<group>"; };
FED4C93198EC989AFB18C04D /* Edges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Edges.swift; sourceTree = "<group>"; };
FEDEA3D2E3B24689EE2C2D07 /* View+Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Environment.swift"; sourceTree = "<group>"; };
FEE8E2B18F627E26CA07D99A /* RunnerCoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerCoreTests.swift; sourceTree = "<group>"; };
FEEB3ECD861EEC2801B03652 /* State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = State.swift; sourceTree = "<group>"; };
FEEC8BA2E9A611FB242868D5 /* LayoutRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutRootView.swift; sourceTree = "<group>"; };
FEF05B9E4558F03213B7E607 /* SwiftTUI */ = {
@ -764,82 +966,86 @@
path = ../../external;
sourceTree = SOURCE_ROOT;
};
00FF02DFBDB02EF7CA6730AD /* log.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE06B75F1D71891F3D634B95 /* log.swift */; };
00FF0428EFF8BC4844DFEEF5 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9FB11AE896BAE161926281 /* Weak.swift */; };
00FF0AA743B1E02D724F5F8C /* Axis.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED12C36473686FE93CB971C /* Axis.swift */; };
00FF0DE18E6C3150EE967582 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE97FC495C03EB6918A8AA5B /* View.swift */; };
00FF0E0C217BCA513AA25E42 /* Bold.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE565F9C1E240AF078068CC4 /* Bold.swift */; };
00FF15120A8D075045D0C31A /* Node+logTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5C2DBA399E0612A054BE2E /* Node+logTree.swift */; };
00FF159F585DA1FE891AC212 /* Italic.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE579D8399C4C1DCC8EED430 /* Italic.swift */; };
00FF17E30E5E434F1A61B03E /* FixedFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3DF55F9C9C4BC3D6031FE4 /* FixedFrame.swift */; };
00FF187F7C193AE2DC5C0569 /* Strikethrough.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0833F786CD2A2EF231EBE5 /* Strikethrough.swift */; };
00FF1BC72723E836422B53B6 /* SwiftTUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE25780E4212F6D462FB9149 /* SwiftTUI.swift */; };
00FF1F7CE9DEE5E71B7FD162 /* Border.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB681E54A115EA32E615BFB /* Border.swift */; };
00FF1F9002855C61CF31D72C /* ArrowKeyParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEA362915EE372841E810442 /* ArrowKeyParser.swift */; };
00FF23D86E413506C6F7DB25 /* Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE669B47061526964E8012FF /* Text.swift */; };
00FF24113C0B99C3349F0761 /* LayoutRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEEC8BA2E9A611FB242868D5 /* LayoutRootView.swift */; };
00FF2570965BBE7BAABB7C8F /* FlexibleFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6CB92FA70E5A7EE190EB1E /* FlexibleFrame.swift */; };
00FF28471707BD8316B43410 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9B6E8AD18CF510CC2C3174 /* Color.swift */; };
00FF29699AA621079339AEA2 /* CellAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB71BE6A8588DC0A820ED8E /* CellAttributes.swift */; };
00FF2C946200B58812B667DF /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEEB3ECD861EEC2801B03652 /* State.swift */; };
00FF2E046DCFA53B787E8B14 /* ForegroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE94FB30E7CAB9941E04149F /* ForegroundColor.swift */; };
00FF33C3B2D6D0317F653F20 /* View+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE28ED61A3E441791C892614 /* View+State.swift */; };
00FF377E17D813E1DF17B011 /* Underline.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3348E7805B88D20C67D624 /* Underline.swift */; };
00FF38B4059491987FAEE965 /* Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE981D88F74E1B0E237FF17A /* Extended.swift */; };
00FF3907B1397417683BA7FC /* HStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE1D5FAB1C88913D40911281 /* HStack.swift */; };
00FF3A4B43C80D488C7CE32B /* LayerDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6C1FBF148386BCCB815946 /* LayerDrawing.swift */; };
00FF3B45C9889ED370565846 /* ObservedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0256EB086C79D047D00FE0 /* ObservedObject.swift */; };
00FF40BBB288C62260CA76C3 /* EscapeSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9FA50882B24965E3924A03 /* EscapeSequence.swift */; };
00FF45B8E101B2B215011288 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFEB64A0F9ECD99B9D903B6 /* TextField.swift */; };
00FF4600097791854D5254C8 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE406681BF50D14C2B003EFA /* Padding.swift */; };
00FF49436AF208504407BD30 /* ASCII.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE97AC026E7A91BD7F6FADDF /* ASCII.swift */; };
00FF4A4ABC004B5FF5637D01 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC35B1294C0C3A5487073C1 /* Environment.swift */; };
00FF5528E4594080E339FE5E /* ZStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECF34CCEB582E63F618344C /* ZStack.swift */; };
00FF5E51E93E85114A81C2ED /* AttributeScopes+SwiftTUIAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7E6DAF3716429D85DF1CB4 /* AttributeScopes+SwiftTUIAttributes.swift */; };
00FF65FFCD86BF306BEC3471 /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE8F75BC675A850D30B1DFF7 /* Divider.swift */; };
00FF69CEE00F16C55B995EA3 /* Rect.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7ADB44C83312F759326BC8 /* Rect.swift */; };
00FF6E0FF588278BC1C0E96E /* ComposedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE36B7FB4825960CFD1EE9A0 /* ComposedView.swift */; };
00FF769EE4F24E03387EE327 /* Control+logTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9EBAED75B41BFE5B66EF7B /* Control+logTree.swift */; };
00FF76C198B892A242BACBA0 /* View+ObservableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEA171F995F100B4E80C25E3 /* View+ObservableObject.swift */; };
00FF79AAF9921EE12F892356 /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE59CDA3C4C23D3DCD619C36 /* Layer.swift */; };
00FF7EBE80C2D2F703193AE2 /* SetEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE39E81DC7BE1BDBF278368B /* SetEnvironment.swift */; };
00FF7FEDD08A068D8D066266 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56EC4E9A199BCE5A4F11A9 /* Button.swift */; };
00FF814531DF6F008282E112 /* VStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE8A46FC66E9580571ECE3D7 /* VStack.swift */; };
00FF8259DABBDE007D9CA96C /* ModifierView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE1D3E792C9AB2D0FEA7D0A2 /* ModifierView.swift */; };
00FF86BDBAB1FB01FC69713C /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF5075DC088803278713767 /* Background.swift */; };
00FF89E95841426E895D81E5 /* Color+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE87BA54DCED0BC71F4DDCBC /* Color+View.swift */; };
00FF8C1E18A733FD0EE6B012 /* Alignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE78B3B9FF062FE5A86D10CB /* Alignment.swift */; };
00FF8FA09DB2BD499064AC64 /* _ConditionalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7CE4A8C0BEDBFEB07D7052 /* _ConditionalView.swift */; };
00FF9443A13020538EDF8602 /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE88BA287622CAA44EEFBB05 /* Cell.swift */; };
00FFA88328D15EA01534CBB6 /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE955B7713691568C9113C22 /* Node.swift */; };
00FFAC2EE02A2748301EB053 /* GeometryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE04B709B3969540B2E9FBF6 /* GeometryReader.swift */; };
00FFAE6A70F1E1714BD84C61 /* ForEach.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE645B3378625EF192815274 /* ForEach.swift */; };
00FFB51099CAC91D5F78F022 /* ViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0FE8D7E60C3D79B2E83B9C /* ViewBuilder.swift */; };
00FFB7DC9A3293ECE8393A58 /* Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE24A664919669AC0926796A /* Binding.swift */; };
00FFB8584ED0017DB11DE731 /* TupleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6E5D2B3020404DBED9B8FA /* TupleView.swift */; };
00FFB9C9BAB730C1E9019D6D /* PrimitiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECDEC291E284E1243C69040 /* PrimitiveView.swift */; };
00FFC6099114A3970F594B5A /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF83A958022D95AB0510862 /* Group.swift */; };
00FFC77584E23F3984779346 /* Edges.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED4C93198EC989AFB18C04D /* Edges.swift */; };
00FFC7BA845C5AB46EEDD9EC /* GenericView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEAF08A52EEFA7CD8D7ACB91 /* GenericView.swift */; };
00FFC927145F56EA91D8C9F9 /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE335FCA49CCC6A3C60B53B5 /* Window.swift */; };
00FFC950564A0A8E85DE76AA /* Control.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE2F2B1FD47D4F1B77B16984 /* Control.swift */; };
00FFCEF1BD7F380C94FAADB0 /* Spacer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFFB379E67528ADA003A9FF /* Spacer.swift */; };
00FFD84E8471C8E5126FC9E0 /* Optional+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7B02AD81BAA59E17ABF025 /* Optional+View.swift */; };
00FFDC2481C8A9ED7403DE2C /* Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE91AD15BF6BBB472852849F /* Position.swift */; };
00FFDFD37AE54401B53A5ABB /* Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE866088E045EAB828EAE645 /* Size.swift */; };
00FFE75BB68A3EF17D60E39C /* EmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7E35A8870F6ECDB585186F /* EmptyView.swift */; };
00FFEE3805EB06CFC8FC03C7 /* View+Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEDEA3D2E3B24689EE2C2D07 /* View+Environment.swift */; };
00FFEE5BFF62FA2C9CE8512D /* WeakSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED14FCCEFFF6DEE187B47AF /* WeakSet.swift */; };
00FFF11402FCE9EA7A96512F /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE48F0B66A1921E14F62F077 /* Application.swift */; };
00FFF2E0DDE16A7D1010746B /* Renderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB6D73210F2E5F83E8C6A60 /* Renderer.swift */; };
00FFF57F463FD5B6941F2333 /* ScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE230A21685D7895A8803FF1 /* ScrollView.swift */; };
00FFFD7F86C6332ACFE8E09A /* OnAppear.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6BA5124AB5DCB7C1C69060 /* OnAppear.swift */; };
01FF556AC73989CC680307A3 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE359F43A055950CD2C4031A /* main.swift */; };
00FF1E5231001920CAE02B34 /* RunnerCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE11C25A4188C21B80521AF7 /* RunnerCore.swift */; };
01FF0A9B8F2DD54D7DC622F9 /* RunnerCoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEE8E2B18F627E26CA07D99A /* RunnerCoreTests.swift */; };
02FF02DFBDB02EF7CA6730AD /* log.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE06B75F1D71891F3D634B95 /* log.swift */; };
02FF0428EFF8BC4844DFEEF5 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9FB11AE896BAE161926281 /* Weak.swift */; };
02FF0AA743B1E02D724F5F8C /* Axis.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED12C36473686FE93CB971C /* Axis.swift */; };
02FF0DE18E6C3150EE967582 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE97FC495C03EB6918A8AA5B /* View.swift */; };
02FF0E0C217BCA513AA25E42 /* Bold.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE565F9C1E240AF078068CC4 /* Bold.swift */; };
02FF15120A8D075045D0C31A /* Node+logTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5C2DBA399E0612A054BE2E /* Node+logTree.swift */; };
02FF159F585DA1FE891AC212 /* Italic.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE579D8399C4C1DCC8EED430 /* Italic.swift */; };
02FF17E30E5E434F1A61B03E /* FixedFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3DF55F9C9C4BC3D6031FE4 /* FixedFrame.swift */; };
02FF187F7C193AE2DC5C0569 /* Strikethrough.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0833F786CD2A2EF231EBE5 /* Strikethrough.swift */; };
02FF1BC72723E836422B53B6 /* SwiftTUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE25780E4212F6D462FB9149 /* SwiftTUI.swift */; };
02FF1F7CE9DEE5E71B7FD162 /* Border.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB681E54A115EA32E615BFB /* Border.swift */; };
02FF1F9002855C61CF31D72C /* ArrowKeyParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEA362915EE372841E810442 /* ArrowKeyParser.swift */; };
02FF23D86E413506C6F7DB25 /* Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE669B47061526964E8012FF /* Text.swift */; };
02FF24113C0B99C3349F0761 /* LayoutRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEEC8BA2E9A611FB242868D5 /* LayoutRootView.swift */; };
02FF2570965BBE7BAABB7C8F /* FlexibleFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6CB92FA70E5A7EE190EB1E /* FlexibleFrame.swift */; };
02FF28471707BD8316B43410 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9B6E8AD18CF510CC2C3174 /* Color.swift */; };
02FF29699AA621079339AEA2 /* CellAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB71BE6A8588DC0A820ED8E /* CellAttributes.swift */; };
02FF2C946200B58812B667DF /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEEB3ECD861EEC2801B03652 /* State.swift */; };
02FF2E046DCFA53B787E8B14 /* ForegroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE94FB30E7CAB9941E04149F /* ForegroundColor.swift */; };
02FF33C3B2D6D0317F653F20 /* View+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE28ED61A3E441791C892614 /* View+State.swift */; };
02FF377E17D813E1DF17B011 /* Underline.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3348E7805B88D20C67D624 /* Underline.swift */; };
02FF38B4059491987FAEE965 /* Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE981D88F74E1B0E237FF17A /* Extended.swift */; };
02FF3907B1397417683BA7FC /* HStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE1D5FAB1C88913D40911281 /* HStack.swift */; };
02FF3A4B43C80D488C7CE32B /* LayerDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6C1FBF148386BCCB815946 /* LayerDrawing.swift */; };
02FF3B45C9889ED370565846 /* ObservedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0256EB086C79D047D00FE0 /* ObservedObject.swift */; };
02FF40BBB288C62260CA76C3 /* EscapeSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9FA50882B24965E3924A03 /* EscapeSequence.swift */; };
02FF45B8E101B2B215011288 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFEB64A0F9ECD99B9D903B6 /* TextField.swift */; };
02FF4600097791854D5254C8 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE406681BF50D14C2B003EFA /* Padding.swift */; };
02FF49436AF208504407BD30 /* ASCII.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE97AC026E7A91BD7F6FADDF /* ASCII.swift */; };
02FF4A4ABC004B5FF5637D01 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC35B1294C0C3A5487073C1 /* Environment.swift */; };
02FF5528E4594080E339FE5E /* ZStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECF34CCEB582E63F618344C /* ZStack.swift */; };
02FF5E51E93E85114A81C2ED /* AttributeScopes+SwiftTUIAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7E6DAF3716429D85DF1CB4 /* AttributeScopes+SwiftTUIAttributes.swift */; };
02FF65FFCD86BF306BEC3471 /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE8F75BC675A850D30B1DFF7 /* Divider.swift */; };
02FF69CEE00F16C55B995EA3 /* Rect.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7ADB44C83312F759326BC8 /* Rect.swift */; };
02FF6E0FF588278BC1C0E96E /* ComposedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE36B7FB4825960CFD1EE9A0 /* ComposedView.swift */; };
02FF769EE4F24E03387EE327 /* Control+logTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE9EBAED75B41BFE5B66EF7B /* Control+logTree.swift */; };
02FF76C198B892A242BACBA0 /* View+ObservableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEA171F995F100B4E80C25E3 /* View+ObservableObject.swift */; };
02FF79AAF9921EE12F892356 /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE59CDA3C4C23D3DCD619C36 /* Layer.swift */; };
02FF7EBE80C2D2F703193AE2 /* SetEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE39E81DC7BE1BDBF278368B /* SetEnvironment.swift */; };
02FF7FEDD08A068D8D066266 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56EC4E9A199BCE5A4F11A9 /* Button.swift */; };
02FF814531DF6F008282E112 /* VStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE8A46FC66E9580571ECE3D7 /* VStack.swift */; };
02FF8259DABBDE007D9CA96C /* ModifierView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE1D3E792C9AB2D0FEA7D0A2 /* ModifierView.swift */; };
02FF86BDBAB1FB01FC69713C /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF5075DC088803278713767 /* Background.swift */; };
02FF89E95841426E895D81E5 /* Color+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE87BA54DCED0BC71F4DDCBC /* Color+View.swift */; };
02FF8C1E18A733FD0EE6B012 /* Alignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE78B3B9FF062FE5A86D10CB /* Alignment.swift */; };
02FF8FA09DB2BD499064AC64 /* _ConditionalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7CE4A8C0BEDBFEB07D7052 /* _ConditionalView.swift */; };
02FF9443A13020538EDF8602 /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE88BA287622CAA44EEFBB05 /* Cell.swift */; };
02FFA88328D15EA01534CBB6 /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE955B7713691568C9113C22 /* Node.swift */; };
02FFAC2EE02A2748301EB053 /* GeometryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE04B709B3969540B2E9FBF6 /* GeometryReader.swift */; };
02FFAE6A70F1E1714BD84C61 /* ForEach.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE645B3378625EF192815274 /* ForEach.swift */; };
02FFB51099CAC91D5F78F022 /* ViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0FE8D7E60C3D79B2E83B9C /* ViewBuilder.swift */; };
02FFB7DC9A3293ECE8393A58 /* Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE24A664919669AC0926796A /* Binding.swift */; };
02FFB8584ED0017DB11DE731 /* TupleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6E5D2B3020404DBED9B8FA /* TupleView.swift */; };
02FFB9C9BAB730C1E9019D6D /* PrimitiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECDEC291E284E1243C69040 /* PrimitiveView.swift */; };
02FFC6099114A3970F594B5A /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF83A958022D95AB0510862 /* Group.swift */; };
02FFC77584E23F3984779346 /* Edges.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED4C93198EC989AFB18C04D /* Edges.swift */; };
02FFC7BA845C5AB46EEDD9EC /* GenericView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEAF08A52EEFA7CD8D7ACB91 /* GenericView.swift */; };
02FFC927145F56EA91D8C9F9 /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE335FCA49CCC6A3C60B53B5 /* Window.swift */; };
02FFC950564A0A8E85DE76AA /* Control.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE2F2B1FD47D4F1B77B16984 /* Control.swift */; };
02FFCEF1BD7F380C94FAADB0 /* Spacer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFFB379E67528ADA003A9FF /* Spacer.swift */; };
02FFD84E8471C8E5126FC9E0 /* Optional+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7B02AD81BAA59E17ABF025 /* Optional+View.swift */; };
02FFDC2481C8A9ED7403DE2C /* Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE91AD15BF6BBB472852849F /* Position.swift */; };
02FFDFD37AE54401B53A5ABB /* Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE866088E045EAB828EAE645 /* Size.swift */; };
02FFE75BB68A3EF17D60E39C /* EmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE7E35A8870F6ECDB585186F /* EmptyView.swift */; };
02FFEE3805EB06CFC8FC03C7 /* View+Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEDEA3D2E3B24689EE2C2D07 /* View+Environment.swift */; };
02FFEE5BFF62FA2C9CE8512D /* WeakSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED14FCCEFFF6DEE187B47AF /* WeakSet.swift */; };
02FFF11402FCE9EA7A96512F /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE48F0B66A1921E14F62F077 /* Application.swift */; };
02FFF2E0DDE16A7D1010746B /* Renderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEB6D73210F2E5F83E8C6A60 /* Renderer.swift */; };
02FFF57F463FD5B6941F2333 /* ScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE230A21685D7895A8803FF1 /* ScrollView.swift */; };
02FFFD7F86C6332ACFE8E09A /* OnAppear.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6BA5124AB5DCB7C1C69060 /* OnAppear.swift */; };
03FF556AC73989CC680307A3 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE359F43A055950CD2C4031A /* main.swift */; };
FF0000000000000000000004 /* Products */ = {
isa = PBXGroup;
children = (
00004EB553A70000000000FF /* libSwiftTUI.a */,
0100FAB81B6F0000000000FF /* StadtRundlauf */,
00001E1FC9CF0000000000FF /* libRunnerCore.a */,
02004EB553A70000000000FF /* libSwiftTUI.a */,
010021D7AEE90000000000FF /* RunnerCoreTests.xctest */,
0300FAB81B6F0000000000FF /* StadtRundlauf */,
);
name = Products;
sourceTree = "<group>";

View file

@ -17,9 +17,20 @@ _BUNDLE_EXTENSIONS = [
_TRIPLE_MATCH = re.compile(r"([^-]+-[^-]+)(-\D+)[^-]*(-.*)?")
_SETTINGS = {
"arm64-apple-macosx RunnerCoreTests.xctest/Contents/MacOS/RunnerCoreTests": {
"c": "-iquote$(PROJECT_DIR) -iquote$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin -O0 -DDEBUG=1 -fstack-protector -fstack-protector-all",
"f": [
"$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/Library/Frameworks",
],
"s": [
"$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/usr/lib",
"$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject",
],
},
"arm64-apple-macosx StadtRundlauf": {
"c": "-iquote$(PROJECT_DIR) -iquote$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin -O0 -DDEBUG=1 -fstack-protector -fstack-protector-all",
"s": [
"$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/m323/Sources/MiniProject",
"$(BAZEL_OUT)/darwin_arm64-dbg-ST-9a5aec5712f9/bin/external/+http_archive+swifttui",
],
},

View file

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "9999"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "NO">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Initialize Bazel Build Output Groups File"
scriptText = "mkdir -p &quot;${BUILD_MARKER_FILE%/*}&quot;&#10;touch &quot;$BUILD_MARKER_FILE&quot;&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00001E1FC9CF000000000001"
BuildableName = "libRunnerCore.a"
BlueprintName = "RunnerCore"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Prepare BazelDependencies"
scriptText = "mkdir -p &quot;$PROJECT_DIR&quot;&#10;&#10;if [[ &quot;${ENABLE_ADDRESS_SANITIZER:-}&quot; == &quot;YES&quot; || \&#10; &quot;${ENABLE_THREAD_SANITIZER:-}&quot; == &quot;YES&quot; || \&#10; &quot;${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}&quot; == &quot;YES&quot; ]]&#10;then&#10; # TODO: Support custom toolchains once clang.sh supports them&#10; cd &quot;$INTERNAL_DIR&quot; || exit 1&#10; ln -shfF &quot;$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib&quot; lib&#10;fi&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00001E1FC9CF000000000001"
BuildableName = "libRunnerCore.a"
BlueprintName = "RunnerCore"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "NO"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00001E1FC9CF000000000001"
BuildableName = "libRunnerCore.a"
BlueprintName = "RunnerCore"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO"
disableMainThreadChecker = "YES"
disablePerformanceAntipatternChecker = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
disableMainThreadChecker = "YES"
disablePerformanceAntipatternChecker = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "NO"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Debug"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "9999"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "NO">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Initialize Bazel Build Output Groups File"
scriptText = "mkdir -p &quot;${BUILD_MARKER_FILE%/*}&quot;&#10;touch &quot;$BUILD_MARKER_FILE&quot;&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "010021D7AEE9000000000001"
BuildableName = "RunnerCoreTests.xctest"
BlueprintName = "RunnerCoreTests"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Prepare BazelDependencies"
scriptText = "mkdir -p &quot;$PROJECT_DIR&quot;&#10;&#10;if [[ &quot;${ENABLE_ADDRESS_SANITIZER:-}&quot; == &quot;YES&quot; || \&#10; &quot;${ENABLE_THREAD_SANITIZER:-}&quot; == &quot;YES&quot; || \&#10; &quot;${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}&quot; == &quot;YES&quot; ]]&#10;then&#10; # TODO: Support custom toolchains once clang.sh supports them&#10; cd &quot;$INTERNAL_DIR&quot; || exit 1&#10; ln -shfF &quot;$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib&quot; lib&#10;fi&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "010021D7AEE9000000000001"
BuildableName = "RunnerCoreTests.xctest"
BlueprintName = "RunnerCoreTests"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "010021D7AEE9000000000001"
BuildableName = "RunnerCoreTests.xctest"
BlueprintName = "RunnerCoreTests"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO"
customLLDBInitFile = "/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj/rules_xcodeproj/bazel.lldbinit"
disableMainThreadChecker = "YES"
disablePerformanceAntipatternChecker = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Update .lldbinit and copy dSYMs"
scriptText = "&quot;$BAZEL_INTEGRATION_DIR/create_lldbinit.sh&quot;&#10;&quot;$BAZEL_INTEGRATION_DIR/copy_dsyms.sh&quot;&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "010021D7AEE9000000000001"
BuildableName = "RunnerCoreTests.xctest"
BlueprintName = "RunnerCoreTests"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "010021D7AEE9000000000001"
BuildableName = "RunnerCoreTests.xctest"
BlueprintName = "RunnerCoreTests"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "BUILD_WORKING_DIRECTORY"
value = "$(BUILT_PRODUCTS_DIR)"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "BUILD_WORKSPACE_DIRECTORY"
value = "$(BUILD_WORKSPACE_DIRECTORY)"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "010021D7AEE9000000000001"
BuildableName = "RunnerCoreTests.xctest"
BlueprintName = "RunnerCoreTests"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
disableMainThreadChecker = "YES"
disablePerformanceAntipatternChecker = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "NO"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Debug"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -14,7 +14,7 @@
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -30,7 +30,7 @@
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -48,7 +48,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -88,7 +88,7 @@
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -101,7 +101,7 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -136,7 +136,7 @@
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -149,7 +149,7 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0100FAB81B6F000000000001"
BlueprintIdentifier = "0300FAB81B6F000000000001"
BuildableName = "StadtRundlauf"
BlueprintName = "StadtRundlauf"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">

View file

@ -14,7 +14,7 @@
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00004EB553A7000000000001"
BlueprintIdentifier = "02004EB553A7000000000001"
BuildableName = "libSwiftTUI.a"
BlueprintName = "SwiftTUI"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -30,7 +30,7 @@
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00004EB553A7000000000001"
BlueprintIdentifier = "02004EB553A7000000000001"
BuildableName = "libSwiftTUI.a"
BlueprintName = "SwiftTUI"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">
@ -48,7 +48,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00004EB553A7000000000001"
BlueprintIdentifier = "02004EB553A7000000000001"
BuildableName = "libSwiftTUI.a"
BlueprintName = "SwiftTUI"
ReferencedContainer = "container:/Users/cediackermann/Projects/m323/Sources/MiniProject/MiniProject.xcodeproj">

View file

@ -0,0 +1,135 @@
import Foundation
// MARK: - Models
public enum AgeGroup: Int, CustomStringConvertible, CaseIterable {
case junior = 1
case adult = 2
case senior = 3
public var description: String {
switch self {
case .junior: return "Junior"
case .adult: return "Adult"
case .senior: return "Senior"
}
}
}
public struct Runner: Equatable {
public let name: String
public let ageGroup: AgeGroup
public let time: String
public let number: Int
public init(name: String, ageGroup: AgeGroup, time: String, number: Int) {
self.name = name
self.ageGroup = ageGroup
self.time = time
self.number = number
}
}
public enum SortKey: String, CaseIterable {
case name
case ageGroup
case time
case number
public func sort(_ lhs: Runner, _ rhs: Runner) -> Bool {
switch self {
case .name: return lhs.name < rhs.name
case .ageGroup: return lhs.ageGroup.rawValue < rhs.ageGroup.rawValue
case .time: return lhs.time < rhs.time
case .number: return lhs.number < rhs.number
}
}
}
// MARK: - IO
public func readFile(_ path: String) -> String {
(try? String(contentsOf: URL(fileURLWithPath: path), encoding: .utf8)) ?? ""
}
// MARK: - Parsing
public func parseResults(_ content: String, separator: String) -> [Int: String] {
let pairs = content
.components(separatedBy: .newlines)
.compactMap { line -> (Int, String)? in
let cols = line.components(separatedBy: separator)
guard cols.count >= 2, let key = Int(cols[0]) else { return nil }
return (key, cols[1])
}
return Dictionary(pairs, uniquingKeysWith: { _, last in last })
}
public func parseStarters(_ content: String, separator: String) -> [(nr: Int, ageGroup: Int, name: String)] {
content
.components(separatedBy: .newlines)
.compactMap { line in
let cols = line.components(separatedBy: separator)
guard cols.count >= 3, let nr = Int(cols[0]), let ageGroup = Int(cols[1])
else { return nil }
return (nr: nr, ageGroup: ageGroup, name: cols[2])
}
}
public func assembleRunners(
starters: [(nr: Int, ageGroup: Int, name: String)], results: [Int: String]
) -> [Runner] {
starters.compactMap { starter in
guard let time = results[starter.nr],
let group = AgeGroup(rawValue: starter.ageGroup)
else {
return nil
}
return Runner(name: starter.name, ageGroup: group, time: time, number: starter.nr)
}
}
public func nonParticipants(
starters: [(nr: Int, ageGroup: Int, name: String)], results: [Int: String]
) -> [Runner] {
starters.compactMap { starter in
guard results[starter.nr] == nil,
let group = AgeGroup(rawValue: starter.ageGroup)
else {
return nil
}
return Runner(name: starter.name, ageGroup: group, time: "DNS", number: starter.nr)
}
}
// MARK: - Transforms
public func visibleRunners(
_ runners: [Runner],
query: String,
includedGroups: Set<AgeGroup>,
sortKey: SortKey
) -> [Runner] {
let needle = query.lowercased()
return runners
.filter { includedGroups.contains($0.ageGroup) }
.filter { needle.isEmpty || $0.name.lowercased().contains(needle) }
.sorted(by: sortKey.sort)
}
public func toggling(_ groups: Set<AgeGroup>, _ group: AgeGroup) -> Set<AgeGroup> {
groups.contains(group) ? groups.subtracting([group]) : groups.union([group])
}
// MARK: - Formatting
public func menuLabel(_ text: String, on: Bool) -> String {
on ? "[\(text)]" : " \(text) "
}
public func formatRow(_ nr: String, _ name: String, _ group: String, _ time: String) -> String {
nr.padding(toLength: 6, withPad: " ", startingAt: 0)
+ name.padding(toLength: 22, withPad: " ", startingAt: 0)
+ group.padding(toLength: 9, withPad: " ", startingAt: 0)
+ time
}

View file

@ -0,0 +1,216 @@
import Foundation
import Testing
import RunnerCore
struct RunnerCoreTests {
// MARK: - AgeGroup
@Test func ageGroupDescription() {
#expect(AgeGroup.junior.description == "Junior")
#expect(AgeGroup.adult.description == "Adult")
#expect(AgeGroup.senior.description == "Senior")
}
@Test func ageGroupRawValueInit() {
#expect(AgeGroup(rawValue: 1) == .junior)
#expect(AgeGroup(rawValue: 3) == .senior)
#expect(AgeGroup(rawValue: 0) == nil)
#expect(AgeGroup(rawValue: 4) == nil)
}
// MARK: - SortKey.sort
private func runner(_ name: String, _ group: AgeGroup, _ time: String, _ nr: Int) -> Runner {
Runner(name: name, ageGroup: group, time: time, number: nr)
}
@Test func sortKeyByName() {
let a = runner("Bob", .adult, "10:00", 2)
let b = runner("Ann", .senior, "09:00", 1)
#expect(SortKey.name.sort(b, a))
#expect(!SortKey.name.sort(a, b))
}
@Test func sortKeyByAgeGroup() {
let junior = runner("X", .junior, "10:00", 5)
let senior = runner("A", .senior, "09:00", 1)
#expect(SortKey.ageGroup.sort(junior, senior))
#expect(!SortKey.ageGroup.sort(senior, junior))
}
@Test func sortKeyByTime() {
let fast = runner("X", .adult, "09:00", 2)
let slow = runner("A", .adult, "10:00", 1)
#expect(SortKey.time.sort(fast, slow))
}
@Test func sortKeyByNumber() {
let first = runner("Z", .adult, "10:00", 1)
let second = runner("A", .adult, "09:00", 2)
#expect(SortKey.number.sort(first, second))
}
// MARK: - readFile
@Test func readFileReturnsContents() throws {
let dir = FileManager.default.temporaryDirectory
let url = dir.appendingPathComponent("runnercore-test-\(UUID().uuidString).txt")
try "hello\nworld".write(to: url, atomically: true, encoding: .utf8)
defer { try? FileManager.default.removeItem(at: url) }
#expect(readFile(url.path) == "hello\nworld")
}
@Test func readFileMissingReturnsEmpty() {
#expect(readFile("/no/such/path/\(UUID().uuidString)") == "")
}
// MARK: - parseResults
@Test func parseResultsValidLines() {
let content = "1\t09:30\n2\t10:15"
let results = parseResults(content, separator: "\t")
#expect(results == [1: "09:30", 2: "10:15"])
}
@Test func parseResultsSkipsMalformed() {
let content = "1\t09:30\nnope\n\n3" // "nope" non-int, empty, "3" has <2 cols
let results = parseResults(content, separator: "\t")
#expect(results == [1: "09:30"])
}
@Test func parseResultsDuplicateKeyKeepsLast() {
let content = "1\tfirst\n1\tsecond"
let results = parseResults(content, separator: "\t")
#expect(results == [1: "second"])
}
// MARK: - parseStarters
@Test func parseStartersValidLines() {
let content = "1\t2\tAlice\n7\t3\tBob"
let starters = parseStarters(content, separator: "\t")
#expect(starters.count == 2)
#expect(starters[0].nr == 1)
#expect(starters[0].ageGroup == 2)
#expect(starters[0].name == "Alice")
#expect(starters[1].name == "Bob")
}
@Test func parseStartersSkipsMalformed() {
let content = "1\t2\tAlice\nx\t2\tBad\n5\t2" // non-int nr, too few cols
let starters = parseStarters(content, separator: "\t")
#expect(starters.count == 1)
#expect(starters[0].name == "Alice")
}
// MARK: - assembleRunners
@Test func assembleRunnersMatchesResults() {
let starters = [(nr: 1, ageGroup: 2, name: "Alice"), (nr: 2, ageGroup: 3, name: "Bob")]
let results = [1: "09:30", 2: "10:00"]
let runners = assembleRunners(starters: starters, results: results)
#expect(runners.count == 2)
#expect(runners[0] == Runner(name: "Alice", ageGroup: .adult, time: "09:30", number: 1))
}
@Test func assembleRunnersSkipsMissingResultAndBadGroup() {
let starters = [
(nr: 1, ageGroup: 2, name: "Alice"),
(nr: 2, ageGroup: 9, name: "Bob"),
]
let results = [2: "10:00"]
let runners = assembleRunners(starters: starters, results: results)
#expect(runners.isEmpty)
}
// MARK: - nonParticipants
@Test func nonParticipantsGetDNS() {
let starters = [(nr: 1, ageGroup: 2, name: "Alice"), (nr: 2, ageGroup: 3, name: "Bob")]
let results = [2: "10:00"] // only Bob finished
let absent = nonParticipants(starters: starters, results: results)
#expect(absent == [Runner(name: "Alice", ageGroup: .adult, time: "DNS", number: 1)])
}
@Test func nonParticipantsSkipsBadGroup() {
let starters = [(nr: 1, ageGroup: 9, name: "Ghost")]
let absent = nonParticipants(starters: starters, results: [:])
#expect(absent.isEmpty)
}
// MARK: - visibleRunners
private var sample: [Runner] {
[
runner("Alice", .junior, "09:00", 1),
runner("Bob", .adult, "10:00", 2),
runner("Charlie", .senior, "08:00", 3),
]
}
@Test func visibleRunnersFiltersByGroup() {
let visible = visibleRunners(
sample, query: "", includedGroups: [.adult], sortKey: .number)
#expect(visible.map(\.name) == ["Bob"])
}
@Test func visibleRunnersQueryIsCaseInsensitive() {
let visible = visibleRunners(
sample, query: "aLiC", includedGroups: Set(AgeGroup.allCases), sortKey: .number)
#expect(visible.map(\.name) == ["Alice"])
}
@Test func visibleRunnersEmptyQueryReturnsAllSorted() {
let visible = visibleRunners(
sample, query: "", includedGroups: Set(AgeGroup.allCases), sortKey: .time)
#expect(visible.map(\.name) == ["Charlie", "Alice", "Bob"])
}
@Test func visibleRunnersEmptyWhenNoGroups() {
let visible = visibleRunners(
sample, query: "", includedGroups: [], sortKey: .number)
#expect(visible.isEmpty)
}
// MARK: - toggling
@Test func togglingAddsWhenAbsent() {
#expect(toggling([.junior], .adult) == [.junior, .adult])
}
@Test func togglingRemovesWhenPresent() {
#expect(toggling([.junior, .adult], .adult) == [.junior])
}
// MARK: - menuLabel
@Test func menuLabelOn() {
#expect(menuLabel("Name", on: true) == "[Name]")
}
@Test func menuLabelOff() {
#expect(menuLabel("Name", on: false) == " Name ")
}
// MARK: - formatRow
@Test func formatRowPadsColumns() {
let row = formatRow("#1", "Alice", "Junior", "09:00")
#expect(row == "#1 Alice Junior 09:00")
#expect(row == "#1".padding(toLength: 6, withPad: " ", startingAt: 0)
+ "Alice".padding(toLength: 22, withPad: " ", startingAt: 0)
+ "Junior".padding(toLength: 9, withPad: " ", startingAt: 0)
+ "09:00")
}
@Test func formatRowTruncatesLongFields() {
// padding(toLength:) truncates when the source is longer than the target.
let longName = String(repeating: "x", count: 30)
let row = formatRow("#1", longName, "Junior", "09:00")
#expect(row.contains(String(repeating: "x", count: 22)))
#expect(!row.contains(String(repeating: "x", count: 23)))
}
}

View file

@ -1,133 +1,7 @@
import Foundation
import RunnerCore
import SwiftTUI
// MARK: - Models
enum AgeGroup: Int, CustomStringConvertible, CaseIterable {
case junior = 1
case adult = 2
case senior = 3
var description: String {
switch self {
case .junior: return "Junior"
case .adult: return "Adult"
case .senior: return "Senior"
}
}
}
struct Runner {
let name: String
let ageGroup: AgeGroup
let time: String
let number: Int
}
enum SortKey: String, CaseIterable {
case name
case ageGroup
case time
case number
func sort(_ lhs: Runner, _ rhs: Runner) -> Bool {
switch self {
case .name: return lhs.name < rhs.name
case .ageGroup: return lhs.ageGroup.rawValue < rhs.ageGroup.rawValue
case .time: return lhs.time < rhs.time
case .number: return lhs.number < rhs.number
}
}
}
// MARK: - IO
func readFile(_ path: String) -> String {
(try? String(contentsOf: URL(fileURLWithPath: path), encoding: .utf8)) ?? ""
}
// MARK: - Parsing
func parseResults(_ content: String, separator: String) -> [Int: String] {
let pairs = content
.components(separatedBy: .newlines)
.compactMap { line -> (Int, String)? in
let cols = line.components(separatedBy: separator)
guard cols.count >= 2, let key = Int(cols[0]) else { return nil }
return (key, cols[1])
}
return Dictionary(pairs, uniquingKeysWith: { _, last in last })
}
func parseStarters(_ content: String, separator: String) -> [(nr: Int, ageGroup: Int, name: String)] {
content
.components(separatedBy: .newlines)
.compactMap { line in
let cols = line.components(separatedBy: separator)
guard cols.count >= 3, let nr = Int(cols[0]), let ageGroup = Int(cols[1])
else { return nil }
return (nr: nr, ageGroup: ageGroup, name: cols[2])
}
}
func assembleRunners(starters: [(nr: Int, ageGroup: Int, name: String)], results: [Int: String])
-> [Runner]
{
starters.compactMap { starter in
guard let time = results[starter.nr],
let group = AgeGroup(rawValue: starter.ageGroup)
else {
return nil
}
return Runner(name: starter.name, ageGroup: group, time: time, number: starter.nr)
}
}
func nonParticipants(starters: [(nr: Int, ageGroup: Int, name: String)], results: [Int: String])
-> [Runner]
{
starters.compactMap { starter in
guard results[starter.nr] == nil,
let group = AgeGroup(rawValue: starter.ageGroup)
else {
return nil
}
return Runner(name: starter.name, ageGroup: group, time: "DNS", number: starter.nr)
}
}
// MARK: - Transforms
func visibleRunners(
_ runners: [Runner],
query: String,
includedGroups: Set<AgeGroup>,
sortKey: SortKey
) -> [Runner] {
let needle = query.lowercased()
return runners
.filter { includedGroups.contains($0.ageGroup) }
.filter { needle.isEmpty || $0.name.lowercased().contains(needle) }
.sorted(by: sortKey.sort)
}
func toggling(_ groups: Set<AgeGroup>, _ group: AgeGroup) -> Set<AgeGroup> {
groups.contains(group) ? groups.subtracting([group]) : groups.union([group])
}
// MARK: - Formatting
func menuLabel(_ text: String, on: Bool) -> String {
on ? "[\(text)]" : " \(text) "
}
func formatRow(_ nr: String, _ name: String, _ group: String, _ time: String) -> String {
nr.padding(toLength: 6, withPad: " ", startingAt: 0)
+ name.padding(toLength: 22, withPad: " ", startingAt: 0)
+ group.padding(toLength: 9, withPad: " ", startingAt: 0)
+ time
}
// MARK: - Configuration
let resultsURL = "/Users/cediackermann/Projects/m323/Sources/MiniProject/data/results.txt"