diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 9830229f94..420a1b0f2c 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -46,7 +46,6 @@ 2813F93827ECC4AA00E305E4 /* FindNavigatorResultList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E201B327E9989900CB86D0 /* FindNavigatorResultList.swift */; }; 2813F93927ECC4C300E305E4 /* NavigatorAreaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287776E627E3413200D46668 /* NavigatorAreaView.swift */; }; 2816F594280CF50500DD548B /* CodeEditSymbols in Frameworks */ = {isa = PBXBuildFile; productRef = 2816F593280CF50500DD548B /* CodeEditSymbols */; }; - 283BDCBD2972EEBD002AFF81 /* Package.resolved in Resources */ = {isa = PBXBuildFile; fileRef = 283BDCBC2972EEBD002AFF81 /* Package.resolved */; }; 283BDCC52972F236002AFF81 /* AcknowledgementsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 283BDCC42972F236002AFF81 /* AcknowledgementsTests.swift */; }; 2847019E27FDDF7600F87B6B /* ProjectNavigatorOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2847019D27FDDF7600F87B6B /* ProjectNavigatorOutlineView.swift */; }; 284DC84F2978B7B400BF2770 /* ContributorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284DC84E2978B7B400BF2770 /* ContributorsView.swift */; }; @@ -82,20 +81,6 @@ 581BFB692926431000D251EC /* WelcomeActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581BFB5C2926431000D251EC /* WelcomeActionView.swift */; }; 581BFB6B2926431000D251EC /* RecentProjectItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581BFB5E2926431000D251EC /* RecentProjectItem.swift */; }; 582213F0291834A500EFE361 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582213EF291834A500EFE361 /* AboutView.swift */; }; - 583E528C29361B39001AB554 /* CodeEditUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583E527529361B39001AB554 /* CodeEditUITests.swift */; }; - 583E528D29361B39001AB554 /* testHelpButtonDark.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527929361B39001AB554 /* testHelpButtonDark.1.png */; }; - 583E528E29361B39001AB554 /* testEffectViewLight.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527A29361B39001AB554 /* testEffectViewLight.1.png */; }; - 583E528F29361B39001AB554 /* testSegmentedControlLight.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527B29361B39001AB554 /* testSegmentedControlLight.1.png */; }; - 583E529029361B39001AB554 /* testSegmentedControlProminentLight.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527C29361B39001AB554 /* testSegmentedControlProminentLight.1.png */; }; - 583E529129361B39001AB554 /* testHelpButtonLight.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527D29361B39001AB554 /* testHelpButtonLight.1.png */; }; - 583E529229361B39001AB554 /* testBranchPickerDark.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527E29361B39001AB554 /* testBranchPickerDark.1.png */; }; - 583E529329361B39001AB554 /* testFontPickerViewDark.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E527F29361B39001AB554 /* testFontPickerViewDark.1.png */; }; - 583E529429361B39001AB554 /* testFontPickerViewLight.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E528029361B39001AB554 /* testFontPickerViewLight.1.png */; }; - 583E529529361B39001AB554 /* testSegmentedControlProminentDark.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E528129361B39001AB554 /* testSegmentedControlProminentDark.1.png */; }; - 583E529629361B39001AB554 /* testSegmentedControlDark.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E528229361B39001AB554 /* testSegmentedControlDark.1.png */; }; - 583E529729361B39001AB554 /* testEffectViewDark.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E528329361B39001AB554 /* testEffectViewDark.1.png */; }; - 583E529829361B39001AB554 /* testBranchPickerLight.1.png in Resources */ = {isa = PBXBuildFile; fileRef = 583E528429361B39001AB554 /* testBranchPickerLight.1.png */; }; - 583E529C29361BAB001AB554 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 583E529B29361BAB001AB554 /* SnapshotTesting */; }; 58710159298EB80000951BA4 /* CEWorkspaceFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58710158298EB80000951BA4 /* CEWorkspaceFileManager.swift */; }; 5878DA82291863F900DD95A3 /* AcknowledgementsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878DA81291863F900DD95A3 /* AcknowledgementsView.swift */; }; 5878DA842918642000DD95A3 /* ParsePackagesResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878DA832918642000DD95A3 /* ParsePackagesResolved.swift */; }; @@ -301,6 +286,8 @@ 6C092EDA2A53A58600489202 /* EditorLayout+StateRestoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C092ED92A53A58600489202 /* EditorLayout+StateRestoration.swift */; }; 6C092EE02A53BFCF00489202 /* WorkspaceStateKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C092EDF2A53BFCF00489202 /* WorkspaceStateKey.swift */; }; 6C0D0C6829E861B000AE4D3F /* SettingsSidebarFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0D0C6729E861B000AE4D3F /* SettingsSidebarFix.swift */; }; + 6C0E2F832BE18B8B0083F212 /* Snapshotting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0E2F822BE18B8B0083F212 /* Snapshotting.swift */; }; + 6C0E2F8F2BE1C2DB0083F212 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0E2F8E2BE1C2DB0083F212 /* SnapshotTesting */; }; 6C0F3A3C2A1D0D5000223D19 /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */; }; 6C147C4029A328BC0089B630 /* SplitViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C147C3F29A328560089B630 /* SplitViewData.swift */; }; 6C147C4129A328BF0089B630 /* EditorLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C147C3E29A3281D0089B630 /* EditorLayout.swift */; }; @@ -319,6 +306,7 @@ 6C2C155D29B4F4E500EA60A5 /* SplitViewReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C155C29B4F4E500EA60A5 /* SplitViewReader.swift */; }; 6C2C156129B4F52F00EA60A5 /* SplitViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C156029B4F52F00EA60A5 /* SplitViewModifiers.swift */; }; 6C2C20172A4016FF0047EDF2 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + 6C35C08F2BE3D77E0081BAD5 /* Package.resolved in Resources */ = {isa = PBXBuildFile; fileRef = 6C35C08D2BE3D7590081BAD5 /* Package.resolved */; }; 6C4104E3297C87A000F472BA /* BlurButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E2297C87A000F472BA /* BlurButtonStyle.swift */; }; 6C4104E6297C884F00F472BA /* AboutDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E5297C884F00F472BA /* AboutDetailView.swift */; }; 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */; }; @@ -327,6 +315,7 @@ 6C48D8F22972DAFC00D6D205 /* Env+IsFullscreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F12972DAFC00D6D205 /* Env+IsFullscreen.swift */; }; 6C48D8F42972DB1A00D6D205 /* Env+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F32972DB1A00D6D205 /* Env+Window.swift */; }; 6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F62972E5F300D6D205 /* WindowObserver.swift */; }; + 6C4B442D2B56D79200BE3B9D /* (null) in Frameworks */ = {isa = PBXBuildFile; }; 6C5228B529A868BD00AC48F6 /* Environment+ContentInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */; }; 6C53AAD829A6C4FD00EE9ED6 /* SplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */; }; 6C578D8129CD294800DC73B2 /* ExtensionActivatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C578D8029CD294800DC73B2 /* ExtensionActivatorView.swift */; }; @@ -349,6 +338,9 @@ 6C6BD70129CD172700235D17 /* ExtensionsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C6BD70029CD172700235D17 /* ExtensionsListView.swift */; }; 6C6BD70429CD17B600235D17 /* ExtensionsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C6BD70329CD17B600235D17 /* ExtensionsManager.swift */; }; 6C7256D729A3D7D000C2D3E0 /* SplitViewControllerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7256D629A3D7D000C2D3E0 /* SplitViewControllerView.swift */; }; + 6C769ED12B49BBB800ADF98B /* CodeEditUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583E527529361B39001AB554 /* CodeEditUITests.swift */; }; + 6C769ED52B49BC5100ADF98B /* EditorLayoutViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C206BE02B47EC1D00F1A16A /* EditorLayoutViewTests.swift */; }; + 6C769ED72B49BC5300ADF98B /* EditorAreaViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C206BD82B47E0FE00F1A16A /* EditorAreaViewTests.swift */; }; 6C7F37FE2A3EA6FA00217B83 /* View+focusedValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7F37FD2A3EA6FA00217B83 /* View+focusedValue.swift */; }; 6C81916729B3E80700B75C92 /* ModifierKeysObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C81916629B3E80700B75C92 /* ModifierKeysObserver.swift */; }; 6C81916B29B41DD300B75C92 /* DequeModule in Frameworks */ = {isa = PBXBuildFile; productRef = 6C81916A29B41DD300B75C92 /* DequeModule */; }; @@ -371,6 +363,7 @@ 6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */; }; 6CBE1CFB2B71DAA6003AC32E /* Loopable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBE1CFA2B71DAA6003AC32E /* Loopable.swift */; }; 6CBE1D002B720565003AC32E /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 6CBE1CFF2B720565003AC32E /* CodeEditSourceEditor */; }; + 6CC1EDDC2B543EA800472EE0 /* WelcomeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CC1EDDB2B543EA800472EE0 /* WelcomeTests.swift */; }; 6CC9E4B229B5669900C97388 /* Environment+ActiveEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CC9E4B129B5669900C97388 /* Environment+ActiveEditor.swift */; }; 6CD03B6A29FC773F001BD1D0 /* SettingsInjector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD03B6929FC773F001BD1D0 /* SettingsInjector.swift */; }; 6CDA84AD284C1BA000C1CC3A /* EditorTabBarContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CDA84AC284C1BA000C1CC3A /* EditorTabBarContextMenu.swift */; }; @@ -379,6 +372,8 @@ 6CE6226B2A2A1C730013085C /* UtilityAreaTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CE6226A2A2A1C730013085C /* UtilityAreaTab.swift */; }; 6CE6226E2A2A1CDE0013085C /* NavigatorTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CE6226D2A2A1CDE0013085C /* NavigatorTab.swift */; }; 6CED16E42A3E660D000EC962 /* String+Lines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CED16E32A3E660D000EC962 /* String+Lines.swift */; }; + 6CF602CF2B4A79E7004A3A4A /* CommandLine+UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF602CE2B4A79E7004A3A4A /* CommandLine+UITests.swift */; }; + 6CF602D22B4C9F79004A3A4A /* CommandLine+LaunchArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF602D12B4C9F79004A3A4A /* CommandLine+LaunchArguments.swift */; }; 6CFF967429BEBCC300182D6F /* FindCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CFF967329BEBCC300182D6F /* FindCommands.swift */; }; 6CFF967629BEBCD900182D6F /* FileCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CFF967529BEBCD900182D6F /* FileCommands.swift */; }; 6CFF967829BEBCF600182D6F /* MainCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CFF967729BEBCF600182D6F /* MainCommands.swift */; }; @@ -531,13 +526,6 @@ remoteGlobalIDString = B658FB2B27DA9E0F00EA4DBD; remoteInfo = CodeEdit; }; - B658FB4827DA9E1000EA4DBD /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = B658FB2427DA9E0F00EA4DBD /* Project object */; - proxyType = 1; - remoteGlobalIDString = B658FB2B27DA9E0F00EA4DBD; - remoteInfo = CodeEdit; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -616,7 +604,6 @@ 28052DFE29730E0B00F4F90A /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 2806E9012979588B000040F4 /* Contributor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contributor.swift; sourceTree = ""; }; 2806E903297958B9000040F4 /* ContributorRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorRowView.swift; sourceTree = ""; }; - 283BDCBC2972EEBD002AFF81 /* Package.resolved */ = {isa = PBXFileReference; lastKnownFileType = text; name = Package.resolved; path = CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved; sourceTree = ""; }; 283BDCC42972F236002AFF81 /* AcknowledgementsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementsTests.swift; sourceTree = ""; }; 2847019D27FDDF7600F87B6B /* ProjectNavigatorOutlineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectNavigatorOutlineView.swift; sourceTree = ""; }; 284DC84E2978B7B400BF2770 /* ContributorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorsView.swift; sourceTree = ""; }; @@ -657,19 +644,6 @@ 581BFB5E2926431000D251EC /* RecentProjectItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentProjectItem.swift; sourceTree = ""; }; 582213EF291834A500EFE361 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = ""; }; 583E527529361B39001AB554 /* CodeEditUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeEditUITests.swift; sourceTree = ""; }; - 583E527929361B39001AB554 /* testHelpButtonDark.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testHelpButtonDark.1.png; sourceTree = ""; }; - 583E527A29361B39001AB554 /* testEffectViewLight.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testEffectViewLight.1.png; sourceTree = ""; }; - 583E527B29361B39001AB554 /* testSegmentedControlLight.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testSegmentedControlLight.1.png; sourceTree = ""; }; - 583E527C29361B39001AB554 /* testSegmentedControlProminentLight.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testSegmentedControlProminentLight.1.png; sourceTree = ""; }; - 583E527D29361B39001AB554 /* testHelpButtonLight.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testHelpButtonLight.1.png; sourceTree = ""; }; - 583E527E29361B39001AB554 /* testBranchPickerDark.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testBranchPickerDark.1.png; sourceTree = ""; }; - 583E527F29361B39001AB554 /* testFontPickerViewDark.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testFontPickerViewDark.1.png; sourceTree = ""; }; - 583E528029361B39001AB554 /* testFontPickerViewLight.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testFontPickerViewLight.1.png; sourceTree = ""; }; - 583E528129361B39001AB554 /* testSegmentedControlProminentDark.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testSegmentedControlProminentDark.1.png; sourceTree = ""; }; - 583E528229361B39001AB554 /* testSegmentedControlDark.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testSegmentedControlDark.1.png; sourceTree = ""; }; - 583E528329361B39001AB554 /* testEffectViewDark.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testEffectViewDark.1.png; sourceTree = ""; }; - 583E528429361B39001AB554 /* testBranchPickerLight.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = testBranchPickerLight.1.png; sourceTree = ""; }; - 583E52A129361BFD001AB554 /* CodeEditUITests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CodeEditUITests-Bridging-Header.h"; sourceTree = ""; }; 58710158298EB80000951BA4 /* CEWorkspaceFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CEWorkspaceFileManager.swift; sourceTree = ""; }; 5878DA81291863F900DD95A3 /* AcknowledgementsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AcknowledgementsView.swift; sourceTree = ""; }; 5878DA832918642000DD95A3 /* ParsePackagesResolved.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParsePackagesResolved.swift; sourceTree = ""; }; @@ -874,6 +848,7 @@ 6C092ED92A53A58600489202 /* EditorLayout+StateRestoration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditorLayout+StateRestoration.swift"; sourceTree = ""; }; 6C092EDF2A53BFCF00489202 /* WorkspaceStateKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceStateKey.swift; sourceTree = ""; }; 6C0D0C6729E861B000AE4D3F /* SettingsSidebarFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSidebarFix.swift; sourceTree = ""; }; + 6C0E2F822BE18B8B0083F212 /* Snapshotting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Snapshotting.swift; sourceTree = ""; }; 6C147C3D29A3281D0089B630 /* Editor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Editor.swift; sourceTree = ""; }; 6C147C3E29A3281D0089B630 /* EditorLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorLayout.swift; sourceTree = ""; }; 6C147C3F29A328560089B630 /* SplitViewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewData.swift; sourceTree = ""; }; @@ -885,10 +860,14 @@ 6C186209298BF5A800C663EA /* RecentProjectsListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentProjectsListView.swift; sourceTree = ""; }; 6C1CC9972B1E770B0002349B /* AsyncFileIterator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncFileIterator.swift; sourceTree = ""; }; 6C1CC99A2B1E7CBC0002349B /* FindNavigatorIndexBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindNavigatorIndexBar.swift; sourceTree = ""; }; + 6C1D32032BE1CEAD00549350 /* CodeEditTestPlan.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = CodeEditTestPlan.xctestplan; sourceTree = ""; }; + 6C206BD82B47E0FE00F1A16A /* EditorAreaViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorAreaViewTests.swift; sourceTree = ""; }; + 6C206BE02B47EC1D00F1A16A /* EditorLayoutViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorLayoutViewTests.swift; sourceTree = ""; }; 6C2C155729B4F49100EA60A5 /* SplitViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewItem.swift; sourceTree = ""; }; 6C2C155929B4F4CC00EA60A5 /* Variadic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Variadic.swift; sourceTree = ""; }; 6C2C155C29B4F4E500EA60A5 /* SplitViewReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewReader.swift; sourceTree = ""; }; 6C2C156029B4F52F00EA60A5 /* SplitViewModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewModifiers.swift; sourceTree = ""; }; + 6C35C08D2BE3D7590081BAD5 /* Package.resolved */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Package.resolved; path = CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved; sourceTree = ""; }; 6C4104E2297C87A000F472BA /* BlurButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurButtonStyle.swift; sourceTree = ""; }; 6C4104E5297C884F00F472BA /* AboutDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutDetailView.swift; sourceTree = ""; }; 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutDefaultView.swift; sourceTree = ""; }; @@ -929,6 +908,7 @@ 6CBA0D502A1BF524002C6FAA /* SegmentedControlImproved.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedControlImproved.swift; sourceTree = ""; }; 6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Caption3.swift"; sourceTree = ""; }; 6CBE1CFA2B71DAA6003AC32E /* Loopable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Loopable.swift; sourceTree = ""; }; + 6CC1EDDB2B543EA800472EE0 /* WelcomeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeTests.swift; sourceTree = ""; }; 6CC9E4B129B5669900C97388 /* Environment+ActiveEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+ActiveEditor.swift"; sourceTree = ""; }; 6CD03B6929FC773F001BD1D0 /* SettingsInjector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsInjector.swift; sourceTree = ""; }; 6CDA84AC284C1BA000C1CC3A /* EditorTabBarContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorTabBarContextMenu.swift; sourceTree = ""; }; @@ -936,6 +916,8 @@ 6CE6226A2A2A1C730013085C /* UtilityAreaTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaTab.swift; sourceTree = ""; }; 6CE6226D2A2A1CDE0013085C /* NavigatorTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigatorTab.swift; sourceTree = ""; }; 6CED16E32A3E660D000EC962 /* String+Lines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Lines.swift"; sourceTree = ""; }; + 6CF602CE2B4A79E7004A3A4A /* CommandLine+UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CommandLine+UITests.swift"; sourceTree = ""; }; + 6CF602D12B4C9F79004A3A4A /* CommandLine+LaunchArguments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CommandLine+LaunchArguments.swift"; sourceTree = ""; }; 6CFF967329BEBCC300182D6F /* FindCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindCommands.swift; sourceTree = ""; }; 6CFF967529BEBCD900182D6F /* FileCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCommands.swift; sourceTree = ""; }; 6CFF967729BEBCF600182D6F /* MainCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainCommands.swift; sourceTree = ""; }; @@ -1003,7 +985,6 @@ B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; B658FB3827DA9E1000EA4DBD /* CodeEdit.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeEdit.entitlements; sourceTree = ""; }; B658FB3D27DA9E1000EA4DBD /* CodeEditTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - B658FB4727DA9E1000EA4DBD /* CodeEditUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B65B10EB2B073913002852CF /* CEContentUnavailableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CEContentUnavailableView.swift; sourceTree = ""; }; B65B10EE2B07C454002852CF /* GitClient+Remote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GitClient+Remote.swift"; sourceTree = ""; }; B65B10F12B07D34F002852CF /* GitRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitRemote.swift; sourceTree = ""; }; @@ -1113,14 +1094,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 583E529C29361BAB001AB554 /* SnapshotTesting in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B658FB4427DA9E1000EA4DBD /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( + 6C4B442D2B56D79200BE3B9D /* (null) in Frameworks */, + 6C0E2F8F2BE1C2DB0083F212 /* SnapshotTesting in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1367,12 +1342,12 @@ 4EE96EC82960562000FFBEA8 /* Documents */ = { isa = PBXGroup; children = ( + 613053582B23916D00D767E3 /* Indexer */, 4EE96ECC296059D200FFBEA8 /* Mocks */, 4EE96ECA2960565E00FFBEA8 /* DocumentsUnitTests.swift */, 6195E3102B640485007261CA /* WorkspaceDocument+SearchState+IndexTests.swift */, 6195E30C2B64044F007261CA /* WorkspaceDocument+SearchState+FindTests.swift */, 6195E30E2B640474007261CA /* WorkspaceDocument+SearchState+FindAndReplaceTests.swift */, - 613053582B23916D00D767E3 /* Indexer */, ); path = Documents; sourceTree = ""; @@ -1547,40 +1522,11 @@ 583E527429361B39001AB554 /* CodeEditUI */ = { isa = PBXGroup; children = ( - 583E527729361B39001AB554 /* __Snapshots__ */, 583E527529361B39001AB554 /* CodeEditUITests.swift */, - 583E52A129361BFD001AB554 /* CodeEditUITests-Bridging-Header.h */, ); path = CodeEditUI; sourceTree = ""; }; - 583E527729361B39001AB554 /* __Snapshots__ */ = { - isa = PBXGroup; - children = ( - 583E527829361B39001AB554 /* UnitTests */, - ); - path = __Snapshots__; - sourceTree = ""; - }; - 583E527829361B39001AB554 /* UnitTests */ = { - isa = PBXGroup; - children = ( - 583E527929361B39001AB554 /* testHelpButtonDark.1.png */, - 583E527A29361B39001AB554 /* testEffectViewLight.1.png */, - 583E527B29361B39001AB554 /* testSegmentedControlLight.1.png */, - 583E527C29361B39001AB554 /* testSegmentedControlProminentLight.1.png */, - 583E527D29361B39001AB554 /* testHelpButtonLight.1.png */, - 583E527E29361B39001AB554 /* testBranchPickerDark.1.png */, - 583E527F29361B39001AB554 /* testFontPickerViewDark.1.png */, - 583E528029361B39001AB554 /* testFontPickerViewLight.1.png */, - 583E528129361B39001AB554 /* testSegmentedControlProminentDark.1.png */, - 583E528229361B39001AB554 /* testSegmentedControlDark.1.png */, - 583E528329361B39001AB554 /* testEffectViewDark.1.png */, - 583E528429361B39001AB554 /* testBranchPickerLight.1.png */, - ); - path = UnitTests; - sourceTree = ""; - }; 5875680E29316BDC00C965A3 /* ShellClient */ = { isa = PBXGroup; children = ( @@ -1741,6 +1687,7 @@ 587B60F329340A8000D5CD8F /* CodeEditTests */ = { isa = PBXGroup; children = ( + 6C1D32032BE1CEAD00549350 /* CodeEditTestPlan.xctestplan */, 587B60FE293416C900D5CD8F /* Features */, 587B60F42934122D00D5CD8F /* Utils */, ); @@ -1751,7 +1698,7 @@ isa = PBXGroup; children = ( 587B61002934170A00D5CD8F /* UnitTests_Extensions.swift */, - 587B60F52934124100D5CD8F /* CEWorkspaceFileManager */, + 6C0E2F822BE18B8B0083F212 /* Snapshotting.swift */, ); path = Utils; sourceTree = ""; @@ -1767,11 +1714,14 @@ 587B60FE293416C900D5CD8F /* Features */ = { isa = PBXGroup; children = ( - 613899BD2B6E70E200A5CAF6 /* Search */, 283BDCC22972F211002AFF81 /* Acknowledgements */, - 4EE96EC82960562000FFBEA8 /* Documents */, + 587B60F52934124100D5CD8F /* CEWorkspaceFileManager */, 583E527429361B39001AB554 /* CodeEditUI */, 587B612C2934199800D5CD8F /* CodeFile */, + 4EE96EC82960562000FFBEA8 /* Documents */, + 6C769ECF2B49BA8C00ADF98B /* Editor */, + 613899BD2B6E70E200A5CAF6 /* Search */, + 6CC1EDD92B543E8100472EE0 /* Welcome */, ); path = Features; sourceTree = ""; @@ -2195,18 +2145,19 @@ 58D01C87293167DC00C5B6B4 /* Extensions */ = { isa = PBXGroup; children = ( - 6C82D6C429C0129E00495C54 /* NSApplication */, 77A01E922BCA9C0400F0EA38 /* NSWindow */, 588847672992AAB800996D95 /* Array */, - 6CBD1BC42978DE3E006639D5 /* Text */, - 5831E3D02934036D00D5A6D2 /* NSTableView */, 6C48B5C82C0B5F7A001E9955 /* NSTextStorage */, - 5831E3CA2933E86F00D5A6D2 /* View */, 5831E3C72933E7F700D5A6D2 /* Bundle */, + 6CF602CD2B4A79B3004A3A4A /* CommandLine */, 5831E3C62933E7E600D5A6D2 /* Color */, 5831E3C82933E80500D5A6D2 /* Date */, + 6C82D6C429C0129E00495C54 /* NSApplication */, + 5831E3D02934036D00D5A6D2 /* NSTableView */, 58D01C8B293167DC00C5B6B4 /* String */, 5831E3CB2933E89A00D5A6D2 /* SwiftTerm */, + 6CBD1BC42978DE3E006639D5 /* Text */, + 5831E3CA2933E86F00D5A6D2 /* View */, ); path = Extensions; sourceTree = ""; @@ -2477,6 +2428,15 @@ path = Extensions; sourceTree = ""; }; + 6C769ECF2B49BA8C00ADF98B /* Editor */ = { + isa = PBXGroup; + children = ( + 6C206BD82B47E0FE00F1A16A /* EditorAreaViewTests.swift */, + 6C206BE02B47EC1D00F1A16A /* EditorLayoutViewTests.swift */, + ); + path = Editor; + sourceTree = ""; + }; 6C82D6BF29C00EE300495C54 /* Utils */ = { isa = PBXGroup; children = ( @@ -2519,6 +2479,23 @@ path = Text; sourceTree = ""; }; + 6CC1EDD92B543E8100472EE0 /* Welcome */ = { + isa = PBXGroup; + children = ( + 6CC1EDDB2B543EA800472EE0 /* WelcomeTests.swift */, + ); + path = Welcome; + sourceTree = ""; + }; + 6CF602CD2B4A79B3004A3A4A /* CommandLine */ = { + isa = PBXGroup; + children = ( + 6CF602D12B4C9F79004A3A4A /* CommandLine+LaunchArguments.swift */, + 6CF602CE2B4A79E7004A3A4A /* CommandLine+UITests.swift */, + ); + path = CommandLine; + sourceTree = ""; + }; 77A01E1A2BB33F1E00F0EA38 /* Views */ = { isa = PBXGroup; children = ( @@ -2664,7 +2641,7 @@ 58F2EACE292FB2B0004A9BDE /* Documentation.docc */, 2BE487ED28245162003F3F64 /* OpenWithCodeEdit */, 284DC8502978BA2600BF2770 /* .all-contributorsrc */, - 283BDCBC2972EEBD002AFF81 /* Package.resolved */, + 6C35C08D2BE3D7590081BAD5 /* Package.resolved */, B658FB2D27DA9E0F00EA4DBD /* Products */, 5C403B8D27E20F8000788241 /* Frameworks */, ); @@ -2677,7 +2654,6 @@ children = ( B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */, B658FB3D27DA9E1000EA4DBD /* CodeEditTests.xctest */, - B658FB4727DA9E1000EA4DBD /* CodeEditUITests.xctest */, 2BE487EC28245162003F3F64 /* OpenWithCodeEdit.appex */, ); name = Products; @@ -3127,32 +3103,12 @@ ); name = CodeEditTests; packageProductDependencies = ( - 583E529B29361BAB001AB554 /* SnapshotTesting */, + 6C0E2F8E2BE1C2DB0083F212 /* SnapshotTesting */, ); productName = CodeEditTests; productReference = B658FB3D27DA9E1000EA4DBD /* CodeEditTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - B658FB4627DA9E1000EA4DBD /* CodeEditUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = B658FB5727DA9E1000EA4DBD /* Build configuration list for PBXNativeTarget "CodeEditUITests" */; - buildPhases = ( - B658FB4327DA9E1000EA4DBD /* Sources */, - B658FB4427DA9E1000EA4DBD /* Frameworks */, - B658FB4527DA9E1000EA4DBD /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - B658FB4927DA9E1000EA4DBD /* PBXTargetDependency */, - ); - name = CodeEditUITests; - packageProductDependencies = ( - ); - productName = CodeEditUITests; - productReference = B658FB4727DA9E1000EA4DBD /* CodeEditUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -3160,7 +3116,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1330; + LastSwiftUpdateCheck = 1500; LastUpgradeCheck = 1430; TargetAttributes = { 2BE487EB28245162003F3F64 = { @@ -3173,11 +3129,6 @@ CreatedOnToolsVersion = 13.1; TestTargetID = B658FB2B27DA9E0F00EA4DBD; }; - B658FB4627DA9E1000EA4DBD = { - CreatedOnToolsVersion = 13.1; - LastSwiftMigration = 1410; - TestTargetID = B658FB2B27DA9E0F00EA4DBD; - }; }; }; buildConfigurationList = B658FB2727DA9E0F00EA4DBD /* Build configuration list for PBXProject "CodeEdit" */; @@ -3194,13 +3145,13 @@ 287136B1292A407E00E9F5F4 /* XCRemoteSwiftPackageReference "SwiftLintPlugin" */, 58798288292ED15F0085B254 /* XCRemoteSwiftPackageReference "SwiftTerm" */, 58F2EB1C292FB954004A9BDE /* XCRemoteSwiftPackageReference "Sparkle" */, - 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */, 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */, 6C6BD6F229CD142C00235D17 /* XCRemoteSwiftPackageReference "collectionconcurrencykit" */, 6C66C31129D05CC800DE9ED2 /* XCRemoteSwiftPackageReference "GRDB.swift" */, 6CDEFC9429E22C2700B7C684 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */, 6CBE1CFE2B720565003AC32E /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */, + 6C0E2F8B2BE1C2C90083F212 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */, 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; @@ -3209,7 +3160,6 @@ targets = ( B658FB2B27DA9E0F00EA4DBD /* CodeEdit */, B658FB3C27DA9E1000EA4DBD /* CodeEditTests */, - B658FB4627DA9E1000EA4DBD /* CodeEditUITests */, 2BE487EB28245162003F3F64 /* OpenWithCodeEdit */, ); }; @@ -3229,12 +3179,12 @@ buildActionMask = 2147483647; files = ( B6FF04782B6C08AC002C2C78 /* DefaultThemes in Resources */, - 283BDCBD2972EEBD002AFF81 /* Package.resolved in Resources */, B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */, 3E0196732A3921AC002648D8 /* codeedit_shell_integration.zsh in Resources */, 58A5DFA529339F6400D1BD5D /* default_keybindings.json in Resources */, 3E01967A2A392B45002648D8 /* codeedit_shell_integration.bash in Resources */, D7211D4727E06BFE008F2ED7 /* Localizable.strings in Resources */, + 6C35C08F2BE3D77E0081BAD5 /* Package.resolved in Resources */, 284DC8512978BA2600BF2770 /* .all-contributorsrc in Resources */, B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */, 6C6BD6FC29CD152400235D17 /* codeedit.extension.appextensionpoint in Resources */, @@ -3242,25 +3192,6 @@ runOnlyForDeploymentPostprocessing = 0; }; B658FB3B27DA9E1000EA4DBD /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 583E529329361B39001AB554 /* testFontPickerViewDark.1.png in Resources */, - 583E529129361B39001AB554 /* testHelpButtonLight.1.png in Resources */, - 583E529029361B39001AB554 /* testSegmentedControlProminentLight.1.png in Resources */, - 583E528F29361B39001AB554 /* testSegmentedControlLight.1.png in Resources */, - 583E529429361B39001AB554 /* testFontPickerViewLight.1.png in Resources */, - 583E529729361B39001AB554 /* testEffectViewDark.1.png in Resources */, - 583E529829361B39001AB554 /* testBranchPickerLight.1.png in Resources */, - 583E528E29361B39001AB554 /* testEffectViewLight.1.png in Resources */, - 583E529229361B39001AB554 /* testBranchPickerDark.1.png in Resources */, - 583E529529361B39001AB554 /* testSegmentedControlProminentDark.1.png in Resources */, - 583E528D29361B39001AB554 /* testHelpButtonDark.1.png in Resources */, - 583E529629361B39001AB554 /* testSegmentedControlDark.1.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B658FB4527DA9E1000EA4DBD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -3406,6 +3337,7 @@ D7E201AE27E8B3C000CB86D0 /* String+Ranges.swift in Sources */, 6CE6226E2A2A1CDE0013085C /* NavigatorTab.swift in Sources */, 041FC6AD2AE437CE00C1F65A /* SourceControlNavigatorNewBranchView.swift in Sources */, + 6CF602CF2B4A79E7004A3A4A /* CommandLine+UITests.swift in Sources */, 77A01E432BBC3A2800F0EA38 /* CETask.swift in Sources */, 6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */, 6CED16E42A3E660D000EC962 /* String+Lines.swift in Sources */, @@ -3635,6 +3567,7 @@ 5B698A0D2B26327800DE9392 /* SearchSettings.swift in Sources */, B685DE7929CC9CCD002860C8 /* StatusBarIcon.swift in Sources */, 587B9DA629300ABD00AC7927 /* ToolbarBranchPicker.swift in Sources */, + 6CF602D22B4C9F79004A3A4A /* CommandLine+LaunchArguments.swift in Sources */, 6C6BD6F629CD145F00235D17 /* ExtensionInfo.swift in Sources */, 04BA7C202AE2D92B00584E1C /* GitClient+Status.swift in Sources */, 58F2EB05292FB2B0004A9BDE /* Settings.swift in Sources */, @@ -3780,11 +3713,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 583E528C29361B39001AB554 /* CodeEditUITests.swift in Sources */, + 6C769ED72B49BC5300ADF98B /* EditorAreaViewTests.swift in Sources */, + 6CC1EDDC2B543EA800472EE0 /* WelcomeTests.swift in Sources */, + 6C769ED12B49BBB800ADF98B /* CodeEditUITests.swift in Sources */, 613053652B23A49300D767E3 /* TemporaryFile.swift in Sources */, 587B60F82934124200D5CD8F /* CEWorkspaceFileManagerTests.swift in Sources */, + 6C0E2F832BE18B8B0083F212 /* Snapshotting.swift in Sources */, 6130535F2B23A31300D767E3 /* MemorySearchTests.swift in Sources */, 587B61012934170A00D5CD8F /* UnitTests_Extensions.swift in Sources */, + 6C769ED52B49BC5100ADF98B /* EditorLayoutViewTests.swift in Sources */, 283BDCC52972F236002AFF81 /* AcknowledgementsTests.swift in Sources */, 4EE96ECB2960565E00FFBEA8 /* DocumentsUnitTests.swift in Sources */, 4EE96ECE296059E000FFBEA8 /* NSHapticFeedbackPerformerMock.swift in Sources */, @@ -3798,13 +3735,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B658FB4327DA9E1000EA4DBD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -3822,11 +3752,6 @@ target = B658FB2B27DA9E0F00EA4DBD /* CodeEdit */; targetProxy = B658FB3E27DA9E1000EA4DBD /* PBXContainerItemProxy */; }; - B658FB4927DA9E1000EA4DBD /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B658FB2B27DA9E0F00EA4DBD /* CodeEdit */; - targetProxy = B658FB4827DA9E1000EA4DBD /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -3970,34 +3895,6 @@ }; name = Alpha; }; - 28052DED2973045200F4F90A /* Alpha */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 28052DFC29730DF600F4F90A /* Alpha.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 38; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; - GENERATE_INFOPLIST_FILE = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "CodeEditUITests/Features/CodeEditUI/CodeEditUITests-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = CodeEdit; - }; - name = Alpha; - }; 28052DEE2973045200F4F90A /* Alpha */ = { isa = XCBuildConfiguration; baseConfigurationReference = 28052DFC29730DF600F4F90A /* Alpha.xcconfig */; @@ -4160,34 +4057,6 @@ }; name = Beta; }; - 28052DF22973045C00F4F90A /* Beta */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 28052DFD29730E0300F4F90A /* Beta.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 38; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; - GENERATE_INFOPLIST_FILE = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "CodeEditUITests/Features/CodeEditUI/CodeEditUITests-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = CodeEdit; - }; - name = Beta; - }; 28052DF32973045C00F4F90A /* Beta */ = { isa = XCBuildConfiguration; baseConfigurationReference = 28052DFD29730E0300F4F90A /* Beta.xcconfig */; @@ -4418,34 +4287,6 @@ }; name = Pre; }; - 8B9A0E142B9FE7D7007E2DBF /* Pre */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 28052DFC29730DF600F4F90A /* Alpha.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 38; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; - GENERATE_INFOPLIST_FILE = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "CodeEditUITests/Features/CodeEditUI/CodeEditUITests-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = CodeEdit; - }; - name = Pre; - }; 8B9A0E152B9FE7D7007E2DBF /* Pre */ = { isa = XCBuildConfiguration; baseConfigurationReference = 28052DFC29730DF600F4F90A /* Alpha.xcconfig */; @@ -4741,63 +4582,6 @@ }; name = Release; }; - B658FB5827DA9E1000EA4DBD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 28052DFB29730DE300F4F90A /* Debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 38; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; - GENERATE_INFOPLIST_FILE = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "CodeEditUITests/Features/CodeEditUI/CodeEditUITests-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = CodeEdit; - }; - name = Debug; - }; - B658FB5927DA9E1000EA4DBD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 28052DFE29730E0B00F4F90A /* Release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 38; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = ""; - GENERATE_INFOPLIST_FILE = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "CodeEditUITests/Features/CodeEditUI/CodeEditUITests-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = CodeEdit; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -4849,18 +4633,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B658FB5727DA9E1000EA4DBD /* Build configuration list for PBXNativeTarget "CodeEditUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B658FB5827DA9E1000EA4DBD /* Debug */, - B658FB5927DA9E1000EA4DBD /* Release */, - 28052DED2973045200F4F90A /* Alpha */, - 8B9A0E142B9FE7D7007E2DBF /* Pre */, - 28052DF22973045C00F4F90A /* Beta */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -4880,14 +4652,6 @@ minimumVersion = 0.2.2; }; }; - 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing.git"; - requirement = { - kind = upToNextMinorVersion; - minimumVersion = 1.14.2; - }; - }; 58798288292ED15F0085B254 /* XCRemoteSwiftPackageReference "SwiftTerm" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/migueldeicaza/SwiftTerm.git"; @@ -4912,6 +4676,14 @@ minimumVersion = 1.3.0; }; }; + 6C0E2F8B2BE1C2C90083F212 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.16.0; + }; + }; 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/CodeEditApp/CodeEditKit"; @@ -4968,11 +4740,6 @@ package = 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */; productName = CodeEditSymbols; }; - 583E529B29361BAB001AB554 /* SnapshotTesting */ = { - isa = XCSwiftPackageProductDependency; - package = 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; - productName = SnapshotTesting; - }; 58798289292ED15F0085B254 /* SwiftTerm */ = { isa = XCSwiftPackageProductDependency; package = 58798288292ED15F0085B254 /* XCRemoteSwiftPackageReference "SwiftTerm" */; @@ -4988,6 +4755,11 @@ package = 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */; productName = LogStream; }; + 6C0E2F8E2BE1C2DB0083F212 /* SnapshotTesting */ = { + isa = XCSwiftPackageProductDependency; + package = 6C0E2F8B2BE1C2C90083F212 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; + productName = SnapshotTesting; + }; 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */ = { isa = XCSwiftPackageProductDependency; package = 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index bc1e0a860c..fc9804e5c8 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -132,17 +132,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-snapshot-testing.git", "state" : { - "revision" : "bb0ea08db8e73324fe6c3727f755ca41a23ff2f4", - "version" : "1.14.2" + "revision" : "625ccca8570773dd84a34ee51a81aa2bc5a4f97a", + "version" : "1.16.0" } }, { "identity" : "swift-syntax", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", + "location" : "https://github.com/apple/swift-syntax", "state" : { - "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d", - "version" : "509.1.1" + "revision" : "fa8f95c2d536d6620cc2f504ebe8a6167c9fc2dd", + "version" : "510.0.1" } }, { diff --git a/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme b/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme index 97eb1050e7..92d90e199d 100644 --- a/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme +++ b/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> @@ -27,6 +27,12 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -89,29 +95,18 @@ - - - - - - - - - - - - - - + + + + NSApp.openSwiftUIWindows { - needToHandleOpen = false - } - - for index in 0..: View { .frame(maxWidth: .infinity, maxHeight: .infinity) .contentShape(Rectangle()) .controlSize(.small) + .accessibilityLabel(label) + .accessibilityHint(description ?? "") + .accessibilityElement(children: .combine) + .accessibilityIdentifier("CEContentUnavailableView " + label) } var body: some View { diff --git a/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift b/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift new file mode 100644 index 0000000000..03db2abe26 --- /dev/null +++ b/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift @@ -0,0 +1,103 @@ +// +// WorkspaceCodeFileView.swift +// CodeEdit +// +// Created by Pavel Kasila on 20.03.22. +// + +import SwiftUI +import UniformTypeIdentifiers +import CodeEditSourceEditor + +struct WorkspaceCodeFileView: View { + + @EnvironmentObject private var editorManager: EditorManager + + @EnvironmentObject private var editor: Editor + + var file: CEWorkspaceFile + var textViewCoordinators: [TextViewCoordinator] = [] + + @State private var update: Bool = false + + @ViewBuilder var codeView: some View { + if let document = file.fileDocument { + Group { + switch document.typeOfFile { + case .some(.text), .some(.data): + CodeFileView(codeFile: document, textViewCoordinators: textViewCoordinators) + default: + otherFileView(document, for: file) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } else { + if update { + Spacer() + } + Spacer() + VStack(spacing: 10) { + ProgressView() + Text("Opening \(file.name)...") + } + Spacer() + .onAppear { + Task.detached { + let contentType = try await file.url.resourceValues(forKeys: [.contentTypeKey]).contentType + let codeFile = try await CodeFileDocument( + for: file.url, + withContentsOf: file.url, + ofType: contentType?.identifier ?? "" + ) + await MainActor.run { + file.fileDocument = codeFile + CodeEditDocumentController.shared.addDocument(codeFile) + update.toggle() + } + } + } + } + } + + @ViewBuilder + private func otherFileView( + _ otherFile: CodeFileDocument, + for item: CEWorkspaceFile + ) -> some View { + VStack(spacing: 0) { + if let url = otherFile.previewItemURL, + let image = NSImage(contentsOf: url), + otherFile.typeOfFile == .image { + GeometryReader { proxy in + if image.size.width > proxy.size.width || image.size.height > proxy.size.height { + OtherFileView(otherFile) + } else { + OtherFileView(otherFile) + .frame( + width: proxy.size.width * (proxy.size.width / image.size.width), + height: proxy.size.height + ) + .position(x: proxy.frame(in: .local).midX, y: proxy.frame(in: .local).midY) + } + } + } else { + OtherFileView(otherFile) + } + } + } + + var body: some View { + codeView + .frame(maxWidth: .infinity, maxHeight: .infinity) + .onHover { hover in + DispatchQueue.main.async { + if hover { + NSCursor.iBeam.push() + } else { + NSCursor.pop() + } + } + } + .accessibilityIdentifier("WorkspaceCodeFileView " + file.id) + } +} diff --git a/CodeEdit/Features/Editor/TabBar/Tabs/Tab/EditorTabView.swift b/CodeEdit/Features/Editor/TabBar/Tabs/Tab/EditorTabView.swift index 13c0306576..aa6d3f19fd 100644 --- a/CodeEdit/Features/Editor/TabBar/Tabs/Tab/EditorTabView.swift +++ b/CodeEdit/Features/Editor/TabBar/Tabs/Tab/EditorTabView.swift @@ -294,6 +294,7 @@ struct EditorTabView: View { } } .id(item.id) + .accessibilityIdentifier("EditorTabView" + item.id + (isTemporary ? " - temporary" : "")) .tabBarContextMenu(item: item, isTemporary: isTemporary) } } diff --git a/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarLeadingAccessories.swift b/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarLeadingAccessories.swift index d330da3e73..c5b1c83735 100644 --- a/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarLeadingAccessories.swift +++ b/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarLeadingAccessories.swift @@ -22,7 +22,7 @@ struct EditorTabBarLeadingAccessories: View { var body: some View { HStack(spacing: 0) { - if let otherEditor { + if otherEditor != nil { EditorTabBarAccessoryIcon( icon: .init(systemName: "multiply"), action: { [weak editor] in @@ -33,6 +33,7 @@ struct EditorTabBarLeadingAccessories: View { .help("Close this Editor") .disabled(editorManager.isFocusingActiveEditor) .opacity(editorManager.isFocusingActiveEditor ? 0.5 : 1) + .accessibilityLabel("Close this Editor") EditorTabBarAccessoryIcon( icon: .init( @@ -50,6 +51,11 @@ struct EditorTabBarLeadingAccessories: View { ? "Unfocus this Editor" : "Focus this Editor" ) + .accessibilityLabel( + editorManager.isFocusingActiveEditor + ? "Unfocus this Editor" + : "Focus this Editor" + ) Divider() .frame(height: 10) @@ -83,6 +89,7 @@ struct EditorTabBarLeadingAccessories: View { } .disabled(editor.historyOffset == editor.history.count-1 || editor.history.isEmpty) .help("Navigate back") + .accessibilityLabel("Navigate Back") Menu { ForEach( @@ -110,6 +117,7 @@ struct EditorTabBarLeadingAccessories: View { } .disabled(editor.historyOffset == 0) .help("Navigate forward") + .accessibilityLabel("Navigate Forward") } .buttonStyle(.icon) .controlSize(.small) diff --git a/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarTrailingAccessories.swift b/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarTrailingAccessories.swift index d938c89859..c2bda8eca6 100644 --- a/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarTrailingAccessories.swift +++ b/CodeEdit/Features/Editor/TabBar/Views/EditorTabBarTrailingAccessories.swift @@ -48,6 +48,7 @@ struct EditorTabBarTrailingAccessories: View { Image(symbol: "square.split.horizontal.plus") } .help("Split Vertically") + .accessibilityLabel("Split Vertically") case (.vertical, true), (.horizontal, false): Button { @@ -56,6 +57,7 @@ struct EditorTabBarTrailingAccessories: View { Image(symbol: "square.split.vertical.plus") } .help("Split Horizontally") + .accessibilityLabel("Split Horizontally") default: EmptyView() diff --git a/CodeEdit/Features/Editor/Views/CodeFileView.swift b/CodeEdit/Features/Editor/Views/CodeFileView.swift index 85572ed915..a42727f1dc 100644 --- a/CodeEdit/Features/Editor/Views/CodeFileView.swift +++ b/CodeEdit/Features/Editor/Views/CodeFileView.swift @@ -122,7 +122,6 @@ struct CodeFileView: View { undoManager: undoManager, coordinators: textViewCoordinators ) - .id(codeFile.fileURL) .background { if colorScheme == .dark { @@ -148,6 +147,7 @@ struct CodeFileView: View { .onChange(of: bracketHighlight) { _ in bracketPairHighlight = getBracketPairHighlight() } + .accessibilityIdentifier("CodeFileView") } private func getLanguage() -> CodeLanguage { diff --git a/CodeEdit/Features/Editor/Views/EditorAreaView.swift b/CodeEdit/Features/Editor/Views/EditorAreaView.swift index 11a63f8d0d..e872969188 100644 --- a/CodeEdit/Features/Editor/Views/EditorAreaView.swift +++ b/CodeEdit/Features/Editor/Views/EditorAreaView.swift @@ -95,5 +95,6 @@ struct EditorAreaView: View { editor.temporaryTab = editor.tabs[0] } } + .accessibilityIdentifier("EditorView") } } diff --git a/CodeEdit/Features/Editor/Views/EditorLayoutView.swift b/CodeEdit/Features/Editor/Views/EditorLayoutView.swift index 0402aae008..ace34eb1fe 100644 --- a/CodeEdit/Features/Editor/Views/EditorLayoutView.swift +++ b/CodeEdit/Features/Editor/Views/EditorLayoutView.swift @@ -44,6 +44,7 @@ struct EditorLayoutView: View { SubEditorLayoutView(data: data, focus: $focus) } } + .accessibilityIdentifier("EditorLayoutView") } struct SubEditorLayoutView: View { @@ -56,6 +57,7 @@ struct EditorLayoutView: View { splitView } .edgesIgnoringSafeArea([.top, .bottom]) + .accessibilityIdentifier("SubEditorLayoutView " + data.axis.description) } var splitView: some View { diff --git a/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift b/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift index 074985d386..6dbd37c000 100644 --- a/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift +++ b/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift @@ -61,5 +61,6 @@ struct NavigatorAreaView: View { } } .environmentObject(workspace) + .accessibilityIdentifier("NavigatorAreaView") } } diff --git a/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift b/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift index bd897f902a..b9052af0cb 100644 --- a/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift +++ b/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift @@ -62,5 +62,6 @@ struct UtilityAreaView: View { .padding(.vertical, 8) .frame(maxHeight: 27) } + .accessibilityIdentifier("UtilityAreaView") } } diff --git a/CodeEdit/Utils/Extensions/CommandLine/CommandLine+LaunchArguments.swift b/CodeEdit/Utils/Extensions/CommandLine/CommandLine+LaunchArguments.swift new file mode 100644 index 0000000000..03bc4dcbb1 --- /dev/null +++ b/CodeEdit/Utils/Extensions/CommandLine/CommandLine+LaunchArguments.swift @@ -0,0 +1,43 @@ +// +// CommandLine+LaunchArguments.swift +// CodeEdit +// +// Created by Khan Winter on 1/8/24. +// + +import Foundation +import AppKit + +extension CommandLine { + /// Finds and opens files passed to the app via command line arguments. + /// - Returns: If any files were opened by this method. + static func openArgumentFiles() -> Bool { + var needToHandleOpen = true + + // If no windows were reopened by NSQuitAlwaysKeepsWindows, do default behavior. + // Non-WindowGroup SwiftUI Windows are still in NSApp.windows when they are closed, + // So we need to think about those. + if NSApp.windows.count > NSApp.openSwiftUIWindows { + needToHandleOpen = false + } + + for index in 0...Binding) -> EditorAreaView + + var body: some View { + editorView($focus) + } + } + + private var directory: URL! + private var files: [EditorInstance] = [] + private var mockWorkspace: WorkspaceDocument! + + // MARK: - Setup + + override func setUp() async throws { + directory = try FileManager.default.url( + for: .developerApplicationDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: true + ) + .appendingPathComponent("CodeEdit", isDirectory: true) + .appendingPathComponent("WorkspaceClientTests", isDirectory: true) + try? FileManager.default.removeItem(at: directory) + try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) + + mockWorkspace = try await WorkspaceDocument(for: directory, withContentsOf: directory, ofType: "") + + // Add a few files + let folder1 = directory.appending(path: "Folder 2") + let folder2 = directory.appending(path: "Longer Folder With Some 💯 SPecial Chars ⁉️") + try FileManager.default.createDirectory( + at: folder1, + withIntermediateDirectories: true + ) + try FileManager.default.createDirectory( + at: folder2, + withIntermediateDirectories: true + ) + + let fileURLs = [ + directory.appending(path: "File 1.txt"), + folder1.appending(path: "Documentation.docc"), + folder2.appending(path: "Makefile") + ] + + for url in fileURLs { + try String("Loren Ipsum").write(to: url, atomically: true, encoding: .utf8) + } + + files = fileURLs.map { EditorInstance(file: CEWorkspaceFile(url: $0)) } + + files[1].file.parent = CEWorkspaceFile(url: folder1) + files[2].file.parent = CEWorkspaceFile(url: folder2) + } + + override func tearDown() async throws { + try? FileManager.default.removeItem(at: directory) + } + + // MARK: - Empty Editor + + func testEmptyEditor() throws { + let view = FocusWrapper { focus in + EditorAreaView(editor: Editor(), focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 400, height: 250), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 400, height: 250), appearance: .dark) + } + + // MARK: - Editor With Single Selection + + func testSingleTab() throws { + let tab = EditorInstance(file: CEWorkspaceFile(url: directory.appending(path: "File 1.txt"))) + + let view = FocusWrapper { focus in + EditorAreaView(editor: Editor(files: [tab], selectedTab: tab), focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 500, height: 250), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 500, height: 250), appearance: .dark) + } + + // MARK: - Editor With Multiple Tabs + + func testMultipleTab() throws { + var view = FocusWrapper { focus in + EditorAreaView(editor: Editor(files: .init(self.files), selectedTab: self.files[2]), focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + // Test multiple tabs in dark and light modes. + snapshot(view: view, named: "Tab 1 - Light", size: .init(width: 600, height: 250), appearance: .light) + snapshot(view: view, named: "Tab 1 - Dark", size: .init(width: 600, height: 250), appearance: .dark) + + // Test overflow + snapshot( + view: view, + named: "Tab 1 - Light - Overflow", + size: .init(width: 300, height: 250), + appearance: .light + ) + snapshot(view: view, named: "Tab 1 - Dark - Overflow", size: .init(width: 300, height: 250), appearance: .dark) + + view = FocusWrapper { focus in + EditorAreaView(editor: Editor(files: .init(self.files), selectedTab: self.files[1]), focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + // Test multiple tabs in dark and light modes. + snapshot(view: view, named: "Tab 2 - Light", size: .init(width: 600, height: 250), appearance: .light) + snapshot(view: view, named: "Tab 2 - Dark", size: .init(width: 600, height: 250), appearance: .dark) + + // Test overflow + snapshot( + view: view, + named: "Tab 2 - Light - Overflow", + size: .init(width: 300, height: 250), + appearance: .light + ) + snapshot(view: view, named: "Tab 2 - Dark - Overflow", size: .init(width: 300, height: 250), appearance: .dark) + } + + // MARK: - Temporary Tab + + func testTemporaryTab() throws { + let editor = Editor(files: .init(self.files), selectedTab: self.files[2]) + editor.temporaryTab = self.files[2] + + var view = FocusWrapper { focus in + EditorAreaView(editor: editor, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Tab 1 - Light", size: .init(width: 600, height: 250), appearance: .light) + snapshot(view: view, named: "Tab 1 - Dark", size: .init(width: 600, height: 250), appearance: .dark) + + editor.temporaryTab = self.files[1] + view = FocusWrapper { focus in + EditorAreaView(editor: editor, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Tab 2 - Light", size: .init(width: 600, height: 250), appearance: .light) + snapshot(view: view, named: "Tab 2 - Dark", size: .init(width: 600, height: 250), appearance: .dark) + } +} diff --git a/CodeEditTests/Features/Editor/EditorLayoutViewTests.swift b/CodeEditTests/Features/Editor/EditorLayoutViewTests.swift new file mode 100644 index 0000000000..a60a5b522b --- /dev/null +++ b/CodeEditTests/Features/Editor/EditorLayoutViewTests.swift @@ -0,0 +1,178 @@ +// +// EditorLayoutViewUITests.swift +// CodeEditTests +// +// Created by Khan Winter on 1/5/24. +// + +@testable import CodeEdit +import Foundation +import SnapshotTesting +import SwiftUI +import XCTest + +final class EditorLayoutViewTests: XCTestCase { + struct FocusWrapper: View { + @FocusState var focus: Editor? + var editorView: (FocusState.Binding) -> EditorLayoutView + + var body: some View { + editorView($focus) + } + } + + private var app: XCUIApplication! + private var directory: URL! + private var files: [EditorInstance] = [] + private var mockWorkspace: WorkspaceDocument! + + // MARK: - Setup + + override func setUp() async throws { + directory = try FileManager.default.url( + for: .developerApplicationDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: true + ) + .appendingPathComponent("CodeEdit", isDirectory: true) + .appendingPathComponent("WorkspaceClientTests", isDirectory: true) + try? FileManager.default.removeItem(at: directory) + try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) + + mockWorkspace = try await WorkspaceDocument(for: directory, withContentsOf: directory, ofType: "") + + // Add a few files + let folder1 = directory.appending(path: "Folder 2") + let folder2 = directory.appending(path: "Longer Folder With Some 💯 SPecial Chars ⁉️") + try FileManager.default.createDirectory( + at: folder1, + withIntermediateDirectories: true + ) + try FileManager.default.createDirectory( + at: folder2, + withIntermediateDirectories: true + ) + + let fileURLs = [ + directory.appending(path: "File 1.txt"), + folder1.appending(path: "Documentation.docc"), + folder2.appending(path: "Makefile") + ] + + for url in fileURLs { + try String("Loren Ipsum").write(to: url, atomically: true, encoding: .utf8) + } + + files = fileURLs.map { EditorInstance(file: CEWorkspaceFile(url: $0)) } + + files[1].file.parent = CEWorkspaceFile(url: folder1) + files[2].file.parent = CEWorkspaceFile(url: folder2) + } + + override func tearDown() async throws { + try? FileManager.default.removeItem(at: directory) + } + + // MARK: - Split Editor + + func testSplitEditorHorizontal() { + let editorLeft = Editor() + let editorRight = Editor() + let layout: EditorLayout = .horizontal(.init(.horizontal, editorLayouts: [.one(editorLeft), .one(editorRight)])) + + let view = FocusWrapper { focus in + EditorLayoutView(layout: layout, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 600, height: 150), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 600, height: 150), appearance: .dark) + } + + func testSplitEditorVertical() { + let editorLeft = Editor() + let editorRight = Editor() + let layout: EditorLayout = .vertical(.init(.vertical, editorLayouts: [.one(editorLeft), .one(editorRight)])) + + let view = FocusWrapper { focus in + EditorLayoutView(layout: layout, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 300, height: 400), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 300, height: 400), appearance: .dark) + } + + // MARK: - Split Editor Single Selection + + func testSplitEditorHorizontalSingleTab() { + let editorLeft = Editor(files: [files[0]], selectedTab: files[0]) + let editorRight = Editor(files: [files[1]], selectedTab: files[1]) + let layout: EditorLayout = .horizontal(.init(.horizontal, editorLayouts: [.one(editorLeft), .one(editorRight)])) + + let view = FocusWrapper { focus in + EditorLayoutView(layout: layout, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 800, height: 800), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 800, height: 800), appearance: .dark) + } + + func testSplitEditorVerticalSingleTab() { + let editorLeft = Editor(files: [files[0]], selectedTab: files[0]) + let editorRight = Editor(files: [files[1]], selectedTab: files[1]) + let layout: EditorLayout = .vertical(.init(.vertical, editorLayouts: [.one(editorLeft), .one(editorRight)])) + + let view = FocusWrapper { focus in + EditorLayoutView(layout: layout, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 800, height: 800), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 800, height: 800), appearance: .dark) + } + + // MARK: - Split Editor Multiple Tabs + + func testSplitEditorHorizontalMultipleTab() { + let editorLeft = Editor(files: .init(files), selectedTab: files[0]) + let editorRight = Editor(files: .init(files), selectedTab: files[1]) + let layout: EditorLayout = .horizontal(.init(.horizontal, editorLayouts: [.one(editorLeft), .one(editorRight)])) + + let view = FocusWrapper { focus in + EditorLayoutView(layout: layout, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 800, height: 800), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 800, height: 800), appearance: .dark) + } + + func testSplitEditorVerticalMultipleTab() { + let editorLeft = Editor(files: .init(files), selectedTab: files[0]) + let editorRight = Editor(files: .init(files), selectedTab: files[1]) + let layout: EditorLayout = .vertical(.init(.vertical, editorLayouts: [.one(editorLeft), .one(editorRight)])) + + let view = FocusWrapper { focus in + EditorLayoutView(layout: layout, focus: focus) + } + .environmentObject(mockWorkspace) + .environmentObject(EditorManager()) + .environmentObject(StatusBarViewModel()) + + snapshot(view: view, named: "Light", size: .init(width: 800, height: 800), appearance: .light) + snapshot(view: view, named: "Dark", size: .init(width: 800, height: 800), appearance: .dark) + } +} diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testEmptyEditor.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testEmptyEditor.Dark.png new file mode 100644 index 0000000000..962f4e3882 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testEmptyEditor.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testEmptyEditor.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testEmptyEditor.Light.png new file mode 100644 index 0000000000..72decbd1dc Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testEmptyEditor.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Dark-Overflow.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Dark-Overflow.png new file mode 100644 index 0000000000..793084f1b2 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Dark-Overflow.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Dark.png new file mode 100644 index 0000000000..991a871706 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Light-Overflow.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Light-Overflow.png new file mode 100644 index 0000000000..201f607c8b Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Light-Overflow.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Light.png new file mode 100644 index 0000000000..720f4b88f5 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-1-Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Dark-Overflow.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Dark-Overflow.png new file mode 100644 index 0000000000..813ee3689e Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Dark-Overflow.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Dark.png new file mode 100644 index 0000000000..3d9679787e Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Light-Overflow.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Light-Overflow.png new file mode 100644 index 0000000000..93eee2698a Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Light-Overflow.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Light.png new file mode 100644 index 0000000000..f5ca3373d8 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testMultipleTab.Tab-2-Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testSingleTab.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testSingleTab.Dark.png new file mode 100644 index 0000000000..c1f5f0634f Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testSingleTab.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testSingleTab.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testSingleTab.Light.png new file mode 100644 index 0000000000..ba3c638b43 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testSingleTab.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-1-Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-1-Dark.png new file mode 100644 index 0000000000..51c2941375 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-1-Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-1-Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-1-Light.png new file mode 100644 index 0000000000..1f0c738ae6 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-1-Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-2-Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-2-Dark.png new file mode 100644 index 0000000000..7e4b0049a3 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-2-Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-2-Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-2-Light.png new file mode 100644 index 0000000000..8764ea88d2 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorAreaViewTests/testTemporaryTab.Tab-2-Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontal.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontal.Dark.png new file mode 100644 index 0000000000..b694087b79 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontal.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontal.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontal.Light.png new file mode 100644 index 0000000000..3a989f55d6 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontal.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalMultipleTab.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalMultipleTab.Dark.png new file mode 100644 index 0000000000..59dac3b85f Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalMultipleTab.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalMultipleTab.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalMultipleTab.Light.png new file mode 100644 index 0000000000..62efaa11e2 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalMultipleTab.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalSingleTab.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalSingleTab.Dark.png new file mode 100644 index 0000000000..7012fc50e2 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalSingleTab.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalSingleTab.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalSingleTab.Light.png new file mode 100644 index 0000000000..58b8c5d2d7 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorHorizontalSingleTab.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVertical.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVertical.Dark.png new file mode 100644 index 0000000000..b1fcae2ac3 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVertical.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVertical.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVertical.Light.png new file mode 100644 index 0000000000..a25cf1930e Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVertical.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalMultipleTab.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalMultipleTab.Dark.png new file mode 100644 index 0000000000..d27004c2a3 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalMultipleTab.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalMultipleTab.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalMultipleTab.Light.png new file mode 100644 index 0000000000..2303a36917 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalMultipleTab.Light.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalSingleTab.Dark.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalSingleTab.Dark.png new file mode 100644 index 0000000000..74444422a9 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalSingleTab.Dark.png differ diff --git a/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalSingleTab.Light.png b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalSingleTab.Light.png new file mode 100644 index 0000000000..3ece59b3e2 Binary files /dev/null and b/CodeEditTests/Features/Editor/__Snapshots__/EditorLayoutViewTests/testSplitEditorVerticalSingleTab.Light.png differ diff --git a/CodeEditTests/Features/Welcome/WelcomeTests.swift b/CodeEditTests/Features/Welcome/WelcomeTests.swift new file mode 100644 index 0000000000..caabbfe266 --- /dev/null +++ b/CodeEditTests/Features/Welcome/WelcomeTests.swift @@ -0,0 +1,52 @@ +// +// UnitTests.swift +// CodeEditModules/WelcomeModuleTests +// +// Created by Ziyuan Zhao on 2022/3/19. +// + +@testable import CodeEdit +import Foundation +import SwiftUI +import XCTest + +final class WelcomeModuleUnitTests: XCTestCase { + + func testRecentProjectItemLightSnapshot() throws { + let view = RecentProjectItem(projectPath: URL(fileURLWithPath: "Project Path")) + snapshot(view: view, size: .init(width: 300, height: 60), appearance: .light) + } + + func testRecentProjectItemDarkSnapshot() throws { + let view = RecentProjectItem(projectPath: URL(fileURLWithPath: "Project Path")) + snapshot(view: view, size: .init(width: 300, height: 60), appearance: .dark) + } + + func testRecentJSFileLightSnapshot() throws { + let view = RecentProjectItem(projectPath: URL(fileURLWithPath: "Project Path/test.js")) + snapshot(view: view, size: .init(width: 300, height: 60), appearance: .light) + } + + func testRecentJSFileDarkSnapshot() throws { + let view = RecentProjectItem(projectPath: URL(fileURLWithPath: "Project Path/test.js")) + snapshot(view: view, size: .init(width: 300, height: 60), appearance: .dark) + } + + func testWelcomeActionViewLightSnapshot() throws { + let view = WelcomeActionView( + iconName: "plus.square", + title: "Create a new file", + action: { } + ) + snapshot(view: view, size: .init(width: 300, height: 60), appearance: .light) + } + + func testWelcomeActionViewDarkSnapshot() throws { + let view = WelcomeActionView( + iconName: "plus.square", + title: "Create a new file", + action: { } + ) + snapshot(view: view, size: .init(width: 300, height: 60), appearance: .dark) + } +} diff --git a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileDarkSnapshot.1.png b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileDarkSnapshot.1.png index 785ae088a0..a775e1a33c 100644 Binary files a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileDarkSnapshot.1.png and b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileDarkSnapshot.1.png differ diff --git a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileLightSnapshot.1.png b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileLightSnapshot.1.png index a1cd77abc8..3c03bf0a8e 100644 Binary files a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileLightSnapshot.1.png and b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentJSFileLightSnapshot.1.png differ diff --git a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemDarkSnapshot.1.png b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemDarkSnapshot.1.png index 154207b264..863ae88323 100644 Binary files a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemDarkSnapshot.1.png and b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemDarkSnapshot.1.png differ diff --git a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemLightSnapshot.1.png b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemLightSnapshot.1.png index 7e7c8f87f8..9aef8c4b92 100644 Binary files a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemLightSnapshot.1.png and b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testRecentProjectItemLightSnapshot.1.png differ diff --git a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewDarkSnapshot.1.png b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewDarkSnapshot.1.png index d2447e7bea..353e5cdb00 100644 Binary files a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewDarkSnapshot.1.png and b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewDarkSnapshot.1.png differ diff --git a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewLightSnapshot.1.png b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewLightSnapshot.1.png index e98b423fb0..99693ff4ce 100644 Binary files a/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewLightSnapshot.1.png and b/CodeEditTests/Features/Welcome/__Snapshots__/WelcomeTests/testWelcomeActionViewLightSnapshot.1.png differ diff --git a/CodeEditTests/Utils/Snapshotting.swift b/CodeEditTests/Utils/Snapshotting.swift new file mode 100644 index 0000000000..642f01d8ac --- /dev/null +++ b/CodeEditTests/Utils/Snapshotting.swift @@ -0,0 +1,174 @@ +// +// Snapshotting.swift +// CodeEditTests +// +// Created by Khan Winter on 4/30/24. +// + +import SnapshotTesting +import XCTest +import AppKit +import SwiftUI + +/// A NSWindow which can be configured in a deterministic way. +public final class GenericWindow: NSWindow { + static let standard = GenericWindow(backingScaleFactor: 1.0, colorSpace: .displayP3) + + public init(backingScaleFactor: CGFloat = 1.0, colorSpace: NSColorSpace? = nil) { + self._backingScaleFactor = backingScaleFactor + self._explicitlySpecifiedColorSpace = colorSpace + + super.init(contentRect: NSRect.zero, styleMask: [], backing: .buffered, defer: true) + } + + private let _explicitlySpecifiedColorSpace: NSColorSpace? + private var _systemSpecifiedColorspace: NSColorSpace? + + private let _backingScaleFactor: CGFloat + override public var backingScaleFactor: CGFloat { + return _backingScaleFactor + } + + override public var colorSpace: NSColorSpace? { + get { + _explicitlySpecifiedColorSpace ?? self._systemSpecifiedColorspace + } + set { + self._systemSpecifiedColorspace = newValue + } + } +} + +/// Appearance of a snapshot +enum Appearance { + case light + case dark +} + +/// Assert a snapshot of a view. +/// - Parameters: +/// - view: The view to assert. +/// - name: An optional name for the snapshot. +/// - recording: Set to true to override any existing snapshots. +/// - timeout: The timeout before failing. +/// - file: The file the test is in. +/// - testName: The name of the test. +/// - line: The line of the caller. +/// - precision: How precisely to compare snapshots. +/// - perceptualPrecision: How precisely to compare snapshots, using a human perception algorithm. +/// - size: The size of the view. +/// - appearance: What appearance to use. +/// - windowForDrawing: The window to use for drawing. In most cases this should be the standard one. +func snapshot( + view: NSView, + named name: String? = nil, + record recording: Bool = false, + timeout: TimeInterval = 5, + file: StaticString = #file, + testName: String = #function, + line: UInt = #line, + precision: Float = 1, + perceptualPrecision: Float = 1, + size: CGSize? = nil, + appearance: Appearance = .light, + windowForDrawing: GenericWindow = .standard +) { + // Code here based on: + // https://github.com/pointfreeco/swift-snapshot-testing/pull/533 + // + // Once that PR is merged, this should be replaced with a simple wrapper around the built-in swift-snapshot + // method for snapshotting views. + // For now, this makes it so we have a consistent screen resolution across test machines whether that's the test + // runner mac mini or a maintainer's macbook pro. + + let initialSize = view.frame.size + if let size = size { + view.frame.size = size + } + guard view.frame.width > 0, view.frame.height > 0 else { + fatalError("View not renderable to image at size \(view.frame.size)") + } + + let initialAppearance = view.appearance + switch appearance { + case .light: + view.appearance = NSAppearance(named: .aqua) + case .dark: + view.appearance = NSAppearance(named: .darkAqua) + } + + precondition( + view.window == nil, + """ + If choosing to draw the view using a new window, the view must not already be attached to an existing window. \ + (We wouldn’t be able to easily restore the view and all its associated constraints to the original window \ + after moving it to the new window.) + """ + ) + windowForDrawing.contentView = NSView() + windowForDrawing.contentView?.addSubview(view) + + let bitmapRep = view.bitmapImageRepForCachingDisplay(in: view.bounds)! + view.cacheDisplay(in: view.bounds, to: bitmapRep) + let image = NSImage(size: view.bounds.size) + image.addRepresentation(bitmapRep) + + assertSnapshot( + of: image, + as: .image(precision: precision, perceptualPrecision: perceptualPrecision), + named: name, + record: recording, + timeout: timeout, + file: file, + testName: testName, + line: line + ) + + view.frame.size = initialSize + view.appearance = initialAppearance +} + +/// Assert a snapshot of a view. +/// - Parameters: +/// - view: The view to assert. +/// - name: An optional name for the snapshot. +/// - recording: Set to true to override any existing snapshots. +/// - timeout: The timeout before failing. +/// - file: The file the test is in. +/// - testName: The name of the test. +/// - line: The line of the caller. +/// - precision: How precisely to compare snapshots. +/// - perceptualPrecision: How precisely to compare snapshots, using a human perception algorithm. +/// - size: The size of the view. +/// - appearance: What appearance to use. +/// - windowForDrawing: The window to use for drawing. In most cases this should be the standard one. +func snapshot( + view: some View, + named name: String? = nil, + record recording: Bool = false, + timeout: TimeInterval = 5, + file: StaticString = #file, + testName: String = #function, + line: UInt = #line, + precision: Float = 1, + perceptualPrecision: Float = 1, + size: CGSize? = nil, + appearance: Appearance = .light, + windowForDrawing: GenericWindow = .standard +) { + let hostingView = NSHostingView(rootView: view.preferredColorScheme(appearance == .light ? .light : .dark)) + snapshot( + view: hostingView, + named: name, + record: recording, + timeout: timeout, + file: file, + testName: testName, + line: line, + precision: precision, + perceptualPrecision: perceptualPrecision, + size: size, + appearance: appearance, + windowForDrawing: windowForDrawing + ) +} diff --git a/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.All-Splits.png b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.All-Splits.png new file mode 100644 index 0000000000..9523f5330c Binary files /dev/null and b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.All-Splits.png differ diff --git a/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.Focused-Editor.png b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.Focused-Editor.png new file mode 100644 index 0000000000..df9f3a58c6 Binary files /dev/null and b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.Focused-Editor.png differ diff --git a/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.No-Splits.png b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.No-Splits.png new file mode 100644 index 0000000000..391fe8a3fd Binary files /dev/null and b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.No-Splits.png differ diff --git a/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.One-Split.png b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.One-Split.png new file mode 100644 index 0000000000..825f6a0216 Binary files /dev/null and b/CodeEditUITests/Features/Editor/__Snapshots__/EditorTests/testEditorView.One-Split.png differ diff --git a/Documentation.docc/Documentation.md b/Documentation.docc/Documentation.md index 5825064d5c..ff593caaa4 100644 --- a/Documentation.docc/Documentation.md +++ b/Documentation.docc/Documentation.md @@ -81,6 +81,10 @@ - ``SearchResultMatchModel`` - ``SearchResultLabel`` +### Testing + +- + ### Utils - ``CodeEditKeychain`` diff --git a/Documentation.docc/Testing/Testing.md b/Documentation.docc/Testing/Testing.md new file mode 100644 index 0000000000..867f00a575 --- /dev/null +++ b/Documentation.docc/Testing/Testing.md @@ -0,0 +1,27 @@ +# Testing + +CodeEdit utilizes Xcode's XCTest suite and PointFreeCo's snapshot library for testing. This document documents the methods for creating tests for both UI elements and Unit tests. + +> Note: This document is likely to change in the future. As of writing (May 1, 2024) CodeEdit's interactive UI tests have been removed due to issues with the test runner. When those tests are added back instructions will be added here to add them. For now, non-interactive tests are all that's necessary. + +## Testing Target & Plan + +The `CodeEditTests` target contains all the code used for tests. It's divided into two folders: Features and Utils. When adding tests for a feature like Git a folder in the Features group should be added and a descriptive file should be added. Make sure to keep alphabetical order when adding new groups and files to the Features group. + +The Utils group is for any extensions or helpers for testing. For instance the snapshot wrapper function, and useful hashing functions are stored here. + +CodeEdit uses Xcode's test plan feature to plan our tests. The only test plan is called `CodeEditTestPlan.xctestplan`. All unit tests should be added automatically to this test plan. + +If a test needs to be disabled or given a specific configuration, new plans can be added to the test plan and specific tests or groups of tests can be disabled in the same place. + +b## Adding Unit Tests + +- Ensure the correct feature folder exists in the Features group. + - If this is a new feature, a new folder should be added. + - If the feature already exists, there likely exists a test suite for the feature you're adding tests to. Use this file for the rest of the instructions. + - If there isn't a relevant test file, create a new swift file with a descriptive name in the feature folder. + + + +## Adding UI Unit Tests +