diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 74e7fe6..c549a24 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -500,8 +500,6 @@ C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4ACA38E25C754C100060C66 /* PhpExtension.swift */; }; C4AD38B228ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AD38B128ECD9D300FA8D83 /* TestableFileSystem.swift */; }; C4AD38B328ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AD38B128ECD9D300FA8D83 /* TestableFileSystem.swift */; }; - C4AD38B528ECE2DB00FA8D83 /* brew-formula.json in Resources */ = {isa = PBXBuildFile; fileRef = C43A8A1F25D9D1D700591B77 /* brew-formula.json */; }; - C4AD38B628ECE56D00FA8D83 /* TestableConfigurations.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40F505428ECA64E004AD45B /* TestableConfigurations.swift */; }; C4AF9F72275445FF00D44ED0 /* valet-config.json in Resources */ = {isa = PBXBuildFile; fileRef = C4AF9F70275445FF00D44ED0 /* valet-config.json */; }; C4AF9F78275447F100D44ED0 /* ValetConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */; }; C4AF9F7A2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; }; @@ -568,6 +566,30 @@ C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DEB7D327A5D60B00834718 /* Stats.swift */; }; C4E0F7ED27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E0F7EC27BEBDA9007475F2 /* NSWindowExtension.swift */; }; C4E0F7EE27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E0F7EC27BEBDA9007475F2 /* NSWindowExtension.swift */; }; + C4E2E84828FC1D93003B070C /* TestableConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E84628FC1D8C003B070C /* TestableConfigurationTest.swift */; }; + C4E2E84A28FC1E70003B070C /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E84928FC1E70003B070C /* DataExtension.swift */; }; + C4E2E84B28FC1E70003B070C /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E84928FC1E70003B070C /* DataExtension.swift */; }; + C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E84928FC1E70003B070C /* DataExtension.swift */; }; + C4E2E84D28FC1E70003B070C /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E84928FC1E70003B070C /* DataExtension.swift */; }; + C4E2E84F28FC22E4003B070C /* brew-formula.json in Resources */ = {isa = PBXBuildFile; fileRef = C43A8A1F25D9D1D700591B77 /* brew-formula.json */; }; + C4E2E85028FC22E4003B070C /* brew-formula.json in Resources */ = {isa = PBXBuildFile; fileRef = C43A8A1F25D9D1D700591B77 /* brew-formula.json */; }; + C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */ = {isa = PBXBuildFile; fileRef = C4E2E85128FC256B003B070C /* brew-services-sudo.json */; }; + C4E2E85528FC256B003B070C /* brew-services-sudo.json in Resources */ = {isa = PBXBuildFile; fileRef = C4E2E85128FC256B003B070C /* brew-services-sudo.json */; }; + C4E2E85628FC256B003B070C /* brew-services-sudo.json in Resources */ = {isa = PBXBuildFile; fileRef = C4E2E85128FC256B003B070C /* brew-services-sudo.json */; }; + C4E2E85828FC256B003B070C /* brew-services-normal.json in Resources */ = {isa = PBXBuildFile; fileRef = C4E2E85228FC256B003B070C /* brew-services-normal.json */; }; + C4E2E85928FC256B003B070C /* brew-services-normal.json in Resources */ = {isa = PBXBuildFile; fileRef = C4E2E85228FC256B003B070C /* brew-services-normal.json */; }; + C4E2E85A28FC256B003B070C /* brew-services-normal.json in Resources */ = {isa = PBXBuildFile; fileRef = C4E2E85228FC256B003B070C /* brew-services-normal.json */; }; + C4E2E85C28FC282B003B070C /* TestableConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E85B28FC282B003B070C /* TestableConfiguration.swift */; }; + C4E2E85D28FC282B003B070C /* TestableConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E85B28FC282B003B070C /* TestableConfiguration.swift */; }; + C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E85B28FC282B003B070C /* TestableConfiguration.swift */; }; + C4E2E85F28FC282B003B070C /* TestableConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E85B28FC282B003B070C /* TestableConfiguration.swift */; }; + C4E2E86128FC28A6003B070C /* brew-services.json in Resources */ = {isa = PBXBuildFile; fileRef = C4F30B06278E195800755FCE /* brew-services.json */; }; + C4E2E86228FC28A6003B070C /* brew-services.json in Resources */ = {isa = PBXBuildFile; fileRef = C4F30B06278E195800755FCE /* brew-services.json */; }; + C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E86328FC2F1B003B070C /* XCPMApplication.swift */; }; + C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E86328FC2F1B003B070C /* XCPMApplication.swift */; }; + C4E2E86728FC2F1B003B070C /* XCPMApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E2E86328FC2F1B003B070C /* XCPMApplication.swift */; }; + C4E2E86928FC3002003B070C /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A1925D9CD1000591B77 /* Utility.swift */; }; + C4E2E86A28FC3002003B070C /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A1925D9CD1000591B77 /* Utility.swift */; }; C4E4404627C56F4700D225E1 /* ValetSite.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4404527C56F4700D225E1 /* ValetSite.swift */; }; C4E4404727C56F4700D225E1 /* ValetSite.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4404527C56F4700D225E1 /* ValetSite.swift */; }; C4E49DE728F764050026AC4E /* ActiveCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE628F764050026AC4E /* ActiveCommand.swift */; }; @@ -815,6 +837,12 @@ C4D9F24A280B69E100DCD39A /* AddProxyVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddProxyVC.swift; sourceTree = ""; }; C4DEB7D327A5D60B00834718 /* Stats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stats.swift; sourceTree = ""; }; C4E0F7EC27BEBDA9007475F2 /* NSWindowExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSWindowExtension.swift; sourceTree = ""; }; + C4E2E84628FC1D8C003B070C /* TestableConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableConfigurationTest.swift; sourceTree = ""; }; + C4E2E84928FC1E70003B070C /* DataExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtension.swift; sourceTree = ""; }; + C4E2E85128FC256B003B070C /* brew-services-sudo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "brew-services-sudo.json"; sourceTree = ""; }; + C4E2E85228FC256B003B070C /* brew-services-normal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "brew-services-normal.json"; sourceTree = ""; }; + C4E2E85B28FC282B003B070C /* TestableConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableConfiguration.swift; sourceTree = ""; }; + C4E2E86328FC2F1B003B070C /* XCPMApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCPMApplication.swift; sourceTree = ""; }; C4E4404527C56F4700D225E1 /* ValetSite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetSite.swift; sourceTree = ""; }; C4E49DE628F764050026AC4E /* ActiveCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveCommand.swift; sourceTree = ""; }; C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandProtocol.swift; sourceTree = ""; }; @@ -1176,6 +1204,8 @@ C459B4BF27F6094100E9B4B4 /* brew */ = { isa = PBXGroup; children = ( + C4E2E85228FC256B003B070C /* brew-services-normal.json */, + C4E2E85128FC256B003B070C /* brew-services-sudo.json */, C43A8A1F25D9D1D700591B77 /* brew-formula.json */, C4F30B06278E195800755FCE /* brew-services.json */, ); @@ -1220,6 +1250,7 @@ C471E6DB28F9AFD10021E251 /* Command */, C471E6DA28F9AFCB0021E251 /* Filesystem */, C413E43328DA3E8F00AE33C7 /* Shell */, + C4E2E84628FC1D8C003B070C /* TestableConfigurationTest.swift */, ); path = Testables; sourceTree = ""; @@ -1241,6 +1272,7 @@ C471E79628F9B4260021E251 /* tests */ = { isa = PBXGroup; children = ( + C4E2E86828FC2FF2003B070C /* Shared */, C471E79228F9B1D30021E251 /* PHP Monitor.xctestplan */, C4F7807A25D7F84B000DBC97 /* unit */, C471E7AE28F9B4940021E251 /* feature */, @@ -1534,6 +1566,16 @@ path = Switcher; sourceTree = ""; }; + C4E2E86828FC2FF2003B070C /* Shared */ = { + isa = PBXGroup; + children = ( + C4E2E86328FC2F1B003B070C /* XCPMApplication.swift */, + C40F505428ECA64E004AD45B /* TestableConfigurations.swift */, + C43A8A1925D9CD1000591B77 /* Utility.swift */, + ); + path = Shared; + sourceTree = ""; + }; C4E49DE528F763E20026AC4E /* Command */ = { isa = PBXGroup; children = ( @@ -1576,7 +1618,6 @@ C4F7807A25D7F84B000DBC97 /* unit */ = { isa = PBXGroup; children = ( - C43A8A1925D9CD1000591B77 /* Utility.swift */, C471E6D928F9AFC20021E251 /* Testables */, C40C7F1C27720E1400DDDCDC /* Test Files */, C4C1019927C65A4D001FACC2 /* Commands */, @@ -1599,10 +1640,10 @@ C4F787A728EF812600790735 /* Testables */ = { isa = PBXGroup; children = ( - C40F505428ECA64E004AD45B /* TestableConfigurations.swift */, C46EBC4928DB966A007ACC74 /* TestableShell.swift */, C4AD38B128ECD9D300FA8D83 /* TestableFileSystem.swift */, C4E49DEC28F764A00026AC4E /* TestableCommand.swift */, + C4E2E85B28FC282B003B070C /* TestableConfiguration.swift */, ); path = Testables; sourceTree = ""; @@ -1618,6 +1659,7 @@ C4E0F7EC27BEBDA9007475F2 /* NSWindowExtension.swift */, C4EB53E628553117006F9937 /* ArrayExtension.swift */, C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */, + C4E2E84928FC1E70003B070C /* DataExtension.swift */, ); path = Extensions; sourceTree = ""; @@ -1762,7 +1804,6 @@ 54FCFD26276C883F004CE748 /* SelectPreferenceView.xib in Resources */, C473319F2470923A009A0597 /* Localizable.strings in Resources */, C4068CA427B0780A00544CD5 /* CheckboxPreferenceView.xib in Resources */, - C4AD38B528ECE2DB00FA8D83 /* brew-formula.json in Resources */, 54FCFD2D276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */, C405A4D024B9B9140062FAFA /* InternetAccessPolicy.strings in Resources */, ); @@ -1772,6 +1813,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + C4E2E85528FC256B003B070C /* brew-services-sudo.json in Resources */, + C4E2E85928FC256B003B070C /* brew-services-normal.json in Resources */, + C4E2E84F28FC22E4003B070C /* brew-formula.json in Resources */, + C4E2E86228FC28A6003B070C /* brew-services.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1779,6 +1824,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + C4E2E85628FC256B003B070C /* brew-services-sudo.json in Resources */, + C4E2E85A28FC256B003B070C /* brew-services-normal.json in Resources */, + C4E2E85028FC22E4003B070C /* brew-formula.json in Resources */, + C4E2E86128FC28A6003B070C /* brew-services.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1794,12 +1843,14 @@ C44F868E2835BD8D005C353A /* phpmon-config.json in Resources */, C43A8A2025D9D1D700591B77 /* brew-formula.json in Resources */, C4AF9F72275445FF00D44ED0 /* valet-config.json in Resources */, + C4E2E85828FC256B003B070C /* brew-services-normal.json in Resources */, C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */, C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */, C4F30B08278E195800755FCE /* brew-services.json in Resources */, 54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */, C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */, C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */, + C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1866,6 +1917,7 @@ C40C7F2827721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */, C463E380284930EE00422731 /* PresetHelper.swift in Sources */, C41C02A927E61A65009F26CB /* ValetSite+Fake.swift in Sources */, + C4E2E85C28FC282B003B070C /* TestableConfiguration.swift in Sources */, C4C0E8DF27F88AEB002D32A9 /* FakeSiteScanner.swift in Sources */, C44B3A4628E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */, C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */, @@ -1920,7 +1972,6 @@ C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */, C45E76142854A65300B4FE0C /* ServicesManager.swift in Sources */, C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */, - C4AD38B628ECE56D00FA8D83 /* TestableConfigurations.swift in Sources */, C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */, C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */, C4C8E81B276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */, @@ -1965,6 +2016,7 @@ C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */, C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */, C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */, + C4E2E84A28FC1E70003B070C /* DataExtension.swift in Sources */, C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */, C42337A3281F19F000459A48 /* Xdebug.swift in Sources */, C4B97B75275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */, @@ -1998,12 +2050,14 @@ C471E83A28F9BB650021E251 /* ValetSite+Fake.swift in Sources */, C471E83B28F9BB650021E251 /* SiteScanner.swift in Sources */, C471E83C28F9BB650021E251 /* ValetSiteScanner.swift in Sources */, + C4E2E86928FC3002003B070C /* Utility.swift in Sources */, C471E83D28F9BB650021E251 /* FakeSiteScanner.swift in Sources */, C471E83F28F9BB650021E251 /* AppDelegate.swift in Sources */, C471E84028F9BB650021E251 /* AppDelegate+MenuOutlets.swift in Sources */, C471E84128F9BB650021E251 /* AppDelegate+Notifications.swift in Sources */, C471E84228F9BB650021E251 /* AppDelegate+InterApp.swift in Sources */, C471E84328F9BB650021E251 /* App.swift in Sources */, + C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */, C471E84428F9BB650021E251 /* App+ActivationPolicy.swift in Sources */, C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */, C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */, @@ -2031,6 +2085,7 @@ C471E85C28F9BB650021E251 /* DomainListWindowController.swift in Sources */, C471E85D28F9BB650021E251 /* DomainListVC.swift in Sources */, C471E85E28F9BB650021E251 /* DomainListVC+ContextMenu.swift in Sources */, + C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */, C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */, C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */, C471E86128F9BB650021E251 /* AddSiteVC.swift in Sources */, @@ -2046,6 +2101,7 @@ C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */, C471E86C28F9BB650021E251 /* Preferences.swift in Sources */, C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */, + C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */, C471E86E28F9BB650021E251 /* MenuBarIcons.swift in Sources */, C471E86F28F9BB650021E251 /* Stats.swift in Sources */, C471E87028F9BB650021E251 /* GlobalKeybindPreference.swift in Sources */, @@ -2141,6 +2197,7 @@ C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */, C471E89628F9BB8F0021E251 /* PMWindowController.swift in Sources */, C471E89728F9BB8F0021E251 /* VersionExtractor.swift in Sources */, + C4E2E86728FC2F1B003B070C /* XCPMApplication.swift in Sources */, C471E89828F9BB8F0021E251 /* ValetProxy.swift in Sources */, C471E89928F9BB8F0021E251 /* ValetProxy+Fake.swift in Sources */, C471E89A28F9BB8F0021E251 /* ProxyScanner.swift in Sources */, @@ -2179,6 +2236,7 @@ C471E8BC28F9BB8F0021E251 /* DomainListPhpCell.swift in Sources */, C471E8BD28F9BB8F0021E251 /* DomainListTypeCell.swift in Sources */, C471E8BE28F9BB8F0021E251 /* DomainListKindCell.swift in Sources */, + C4E2E86A28FC3002003B070C /* Utility.swift in Sources */, C471E8BF28F9BB8F0021E251 /* DomainListWindowController.swift in Sources */, C471E8C028F9BB8F0021E251 /* DomainListVC.swift in Sources */, C471E8C128F9BB8F0021E251 /* DomainListVC+ContextMenu.swift in Sources */, @@ -2196,6 +2254,7 @@ C471E8CD28F9BB8F0021E251 /* PrefsVC.swift in Sources */, C471E8CE28F9BB8F0021E251 /* PreferenceName.swift in Sources */, C471E8CF28F9BB8F0021E251 /* Preferences.swift in Sources */, + C4E2E84D28FC1E70003B070C /* DataExtension.swift in Sources */, C471E8D028F9BB8F0021E251 /* CustomPrefs.swift in Sources */, C471E8D128F9BB8F0021E251 /* MenuBarIcons.swift in Sources */, C471E8D228F9BB8F0021E251 /* Stats.swift in Sources */, @@ -2217,6 +2276,7 @@ C471E8E628F9BB8F0021E251 /* VersionPopoverView.swift in Sources */, C471E8E728F9BB8F0021E251 /* NoDomainResultsView.swift in Sources */, C471E8E828F9BB8F0021E251 /* ServicesView.swift in Sources */, + C4E2E85F28FC282B003B070C /* TestableConfiguration.swift in Sources */, C471E8E928F9BB8F0021E251 /* StatsView.swift in Sources */, C471E8EA28F9BB8F0021E251 /* SectionHeaderView.swift in Sources */, C471E8EB28F9BB8F0021E251 /* HeaderView.swift in Sources */, @@ -2351,10 +2411,12 @@ C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */, C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */, C485707B28BF458900539B36 /* VersionPopoverView.swift in Sources */, + C4E2E85D28FC282B003B070C /* TestableConfiguration.swift in Sources */, C485706E28BF451C00539B36 /* OnboardingWindowController.swift in Sources */, C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */, C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */, C42759682627662800093CAE /* NSMenuExtension.swift in Sources */, + C4E2E84828FC1D93003B070C /* TestableConfigurationTest.swift in Sources */, C4D936CB27E3EE4A00BD69FE /* DomainListCellProtocol.swift in Sources */, C4B97B76275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */, C4F780CD25D80B75000DBC97 /* Alert.swift in Sources */, @@ -2382,6 +2444,7 @@ 54D9E0B327E4F51E003B9AD9 /* HotKeysController.swift in Sources */, 03E36FE828D9219000636F7F /* ActiveShell.swift in Sources */, C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */, + C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */, C4E49DE828F764050026AC4E /* ActiveCommand.swift in Sources */, C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */, C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */, @@ -2390,6 +2453,7 @@ C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */, C4CDA894288F1A71007CE25F /* Keys.swift in Sources */, C4D936CA27E3EB6100BD69FE /* PhpHelper.swift in Sources */, + C4E2E84B28FC1E70003B070C /* DataExtension.swift in Sources */, C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */, C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */, 54FCFD31276C8DA4004CE748 /* HotkeyPreferenceView.swift in Sources */, diff --git a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme index 1418749..2f5fe3c 100644 --- a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme +++ b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme @@ -79,12 +79,12 @@ isEnabled = "NO"> + argument = "--configuration:/tmp/pmc_broken.json" + isEnabled = "NO"> diff --git a/phpmon/Common/Extensions/DataExtension.swift b/phpmon/Common/Extensions/DataExtension.swift new file mode 100644 index 0000000..1608b93 --- /dev/null +++ b/phpmon/Common/Extensions/DataExtension.swift @@ -0,0 +1,19 @@ +// +// DataExtension.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 16/10/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import Foundation + +extension Data { + var prettyPrintedJSONString: NSString? { + guard let object = try? JSONSerialization.jsonObject(with: self, options: []), + let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]), + let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return nil } + + return prettyPrintedString + } +} diff --git a/phpmon/Common/Extensions/StringExtension.swift b/phpmon/Common/Extensions/StringExtension.swift index a67b0d4..4c24f3d 100644 --- a/phpmon/Common/Extensions/StringExtension.swift +++ b/phpmon/Common/Extensions/StringExtension.swift @@ -47,6 +47,11 @@ extension String { return !NSArray(object: self).filtered(using: pred).isEmpty } + static func random(_ length: Int) -> String { + let characters = "0123456789abcdefghijklmnopqrstuvwxyz" + return String((0..) -> String { let start = r.lowerBound let end = r.upperBound diff --git a/phpmon/Common/Shell/ShellProtocol.swift b/phpmon/Common/Shell/ShellProtocol.swift index 3b84304..a6e2fed 100644 --- a/phpmon/Common/Shell/ShellProtocol.swift +++ b/phpmon/Common/Shell/ShellProtocol.swift @@ -48,7 +48,7 @@ protocol ShellProtocol { ) async throws -> (Process, ShellOutput) } -enum ShellStream { +enum ShellStream: Codable { case stdOut, stdErr, stdIn } diff --git a/phpmon/Common/Testables/TestableConfiguration.swift b/phpmon/Common/Testables/TestableConfiguration.swift new file mode 100644 index 0000000..b27ac18 --- /dev/null +++ b/phpmon/Common/Testables/TestableConfiguration.swift @@ -0,0 +1,40 @@ +// +// TestableConfiguration.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 16/10/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import Foundation + +public struct TestableConfiguration: Codable { + var architecture: String + var filesystem: [String: FakeFile] + var shellOutput: [String: BatchFakeShellOutput] + var commandOutput: [String: String] + + func apply() { + ActiveShell.useTestable(shellOutput) + ActiveFileSystem.useTestable(filesystem) + ActiveCommand.useTestable(commandOutput) + } + + func toJson(pretty: Bool = false) -> String { + let data = try! JSONEncoder().encode(self) + + if pretty { + return data.prettyPrintedJSONString! as String + } + + return String(data: data, encoding: .utf8)! + } + + static func loadFrom(path: String) -> TestableConfiguration { + return try! JSONDecoder().decode( + TestableConfiguration.self, + from: try! String(contentsOf: URL(fileURLWithPath: path), encoding: .utf8) + .data(using: .utf8)! + ) + } +} diff --git a/phpmon/Common/Testables/TestableFileSystem.swift b/phpmon/Common/Testables/TestableFileSystem.swift index f5b4964..ca6f41b 100644 --- a/phpmon/Common/Testables/TestableFileSystem.swift +++ b/phpmon/Common/Testables/TestableFileSystem.swift @@ -52,11 +52,11 @@ class TestableFileSystem: FileSystemProtocol { } } -enum FakeFileType { +enum FakeFileType: Codable { case binary, text, directory, symlink } -struct FakeFile { +struct FakeFile: Codable { var type: FakeFileType var content: String? diff --git a/phpmon/Common/Testables/TestableShell.swift b/phpmon/Common/Testables/TestableShell.swift index 3cb9984..9ab9c93 100644 --- a/phpmon/Common/Testables/TestableShell.swift +++ b/phpmon/Common/Testables/TestableShell.swift @@ -55,7 +55,7 @@ public class TestableShell: ShellProtocol { } } -struct FakeShellOutput { +struct FakeShellOutput: Codable { let delay: TimeInterval let output: String let stream: ShellStream @@ -69,7 +69,7 @@ struct FakeShellOutput { } } -struct BatchFakeShellOutput { +struct BatchFakeShellOutput: Codable { var items: [FakeShellOutput] static func with(_ items: [FakeShellOutput]) -> BatchFakeShellOutput { diff --git a/phpmon/Domain/App/AppDelegate.swift b/phpmon/Domain/App/AppDelegate.swift index 4e0ada5..0716271 100644 --- a/phpmon/Domain/App/AppDelegate.swift +++ b/phpmon/Domain/App/AppDelegate.swift @@ -87,19 +87,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele self.phpEnvironment = PhpEnv.shared } - static func initializeTestingProfile(_ profile: String) { - Log.info("The profile `\(profile)` is being requested...") - - switch profile { - case "broken": - Log.info("Applying broken PHP Monitor configuration profile!") - TestableConfigurations.broken.apply() - case "working": - Log.info("Applying working PHP Monitor configuration profile!") - TestableConfigurations.working.apply() - default: - assert(true, "No profile for this name is supported.") - } + static func initializeTestingProfile(_ path: String) { + Log.info("The configuration with path `\(path)` is being requested...") + TestableConfiguration + .loadFrom(path: path) + .apply() } // MARK: - Lifecycle diff --git a/phpmon/Common/Testables/TestableConfigurations.swift b/tests/Shared/TestableConfigurations.swift similarity index 62% rename from phpmon/Common/Testables/TestableConfigurations.swift rename to tests/Shared/TestableConfigurations.swift index e36e447..1c77e5a 100644 --- a/phpmon/Common/Testables/TestableConfigurations.swift +++ b/tests/Shared/TestableConfigurations.swift @@ -8,37 +8,7 @@ import Foundation -struct TestableConfiguration { - let architecture: String - let filesystem: [String: FakeFile] - let shellOutput: [String: BatchFakeShellOutput] - let commandOutput: [String: String] - - func apply() { - ActiveShell.useTestable(shellOutput) - ActiveFileSystem.useTestable(filesystem) - ActiveCommand.useTestable(commandOutput) - } -} - -// swiftlint:disable colon trailing_comma class TestableConfigurations { - - /** A broken system, that will not get past initialization due to missing binaries. */ - static var broken: TestableConfiguration { - return TestableConfiguration( - architecture: "arm64", - filesystem: [:], - shellOutput: [ - "id -un" : .instant("username"), - "php -v" : .instant(""), - "ls /opt/homebrew/opt | grep php" : .instant(""), - "valet --version" : .instant("zsh: command not found: valet") - ], - commandOutput: [:] - ) - } - /** A functional, working system setup that is compatible with PHP Monitor. */ static var working: TestableConfiguration { return TestableConfiguration( @@ -59,7 +29,9 @@ class TestableConfigurations { "/opt/homebrew/Cellar/php/8.1.10_1/bin/php-config" : .fake(.binary), "~/.config/valet" - : .fake(.directory) + : .fake(.directory), + "/opt/homebrew/etc/php/8.1/php-fpm.d/valet-fpm.conf" + : .fake(.text) ], shellOutput: [ "sysctl -n sysctl.proc_translated" @@ -69,13 +41,40 @@ class TestableConfigurations { "which node" : .instant("/opt/homebrew/bin/node"), "php -v" - : .instant(ShellStrings.phpVersion), + : .instant(""" + PHP 8.1.10 (cli) (built: Sep 3 2022 12:09:27) (NTS) + Copyright (c) The PHP Group + Zend Engine v4.1.10, Copyright (c) Zend Technologies + with Zend OPcache v8.1.10, Copyright (c), by Zend Technologies + """), "ls /opt/homebrew/opt | grep php" : .instant("php"), "ls /opt/homebrew/opt | grep php@" : .instant("php@8.1"), "sudo /opt/homebrew/bin/brew services info nginx --json" - : .delayed(0.2, ShellStrings.nginxJson), + : .delayed(0.2, """ + [ + { + "name": "nginx", + "service_name": "homebrew.mxcl.nginx", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 133, + "exit_code": 0, + "user": "root", + "status": "started", + "file": "/Library/LaunchDaemons/homebrew.mxcl.nginx.plist", + "command": "/opt/homebrew/opt/nginx/bin/nginx -g daemon off;", + "working_dir": "/opt/homebrew", + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + } + ] + """), "cat /private/etc/sudoers.d/brew" : .instant(""" Cmnd_Alias BREW = /opt/homebrew/bin/brew * @@ -102,8 +101,6 @@ class TestableConfigurations { : .instant(""), "mkdir -p ~/.config/phpmon/bin" : .instant(""), - "/opt/homebrew/bin/brew info php --json" - : .instant(ShellStrings.brewJson), "brew info shivammathur/php/php --json" : .instant("Error: No available formula with the name \"shivammathur/php/php\"."), "/usr/bin/open -Ra \"PhpStorm\"" @@ -116,6 +113,14 @@ class TestableConfigurations { : .instant("Unable to find application named 'Sublime Merge'", .stdErr), "/usr/bin/open -Ra \"iTerm\"" : .instant("Unable to find application named 'iTerm'", .stdErr), + "/opt/homebrew/bin/brew info php --json" + : .instant(ShellStrings.shared.brewJson), + "sudo /opt/homebrew/bin/brew services info --all --json" + : .instant(ShellStrings.shared.brewServicesAsRoot), + "/opt/homebrew/bin/brew services info --all --json" + : .instant(ShellStrings.shared.brewServicesAsUser), + "curl -s --max-time 5 '\(Constants.Urls.StableBuildCaskFile.absoluteString)' | grep version" + : .instant("version '5.6.2_976'") ], commandOutput: [ "/opt/homebrew/bin/php-config --version": "8.1.10", @@ -134,43 +139,24 @@ class TestableConfigurations { } } -struct ShellStrings { +class ShellStrings { + static var shared = ShellStrings() - static let phpVersion = """ - PHP 8.1.10 (cli) (built: Sep 3 2022 12:09:27) (NTS) - Copyright (c) The PHP Group - Zend Engine v4.1.10, Copyright (c) Zend Technologies - with Zend OPcache v8.1.10, Copyright (c), by Zend Technologies - """ + var brewJson: String = "" + var brewServicesAsUser: String = "" + var brewServicesAsRoot: String = "" - static let nginxJson = """ - [ - { - "name": "nginx", - "service_name": "homebrew.mxcl.nginx", - "running": true, - "loaded": true, - "schedulable": false, - "pid": 133, - "exit_code": 0, - "user": "root", - "status": "started", - "file": "/Library/LaunchDaemons/homebrew.mxcl.nginx.plist", - "command": "/opt/homebrew/opt/nginx/bin/nginx -g daemon off;", - "working_dir": "/opt/homebrew", - "root_dir": null, - "log_path": null, - "error_log_path": null, - "interval": null, - "cron": null - } - ] - """ + init() { + self.brewJson = loadFile("brew-formula") + self.brewServicesAsUser = loadFile("brew-services-normal") + self.brewServicesAsRoot = loadFile("brew-services-sudo") + } - static let brewJson: String = { - return try! String(contentsOf: Bundle.main.url( - forResource: "brew-formula", - withExtension: "json" + private func loadFile(_ fileName: String, fileExtension: String = "json") -> String { + let bundle = Bundle(for: type(of: self)) + return try! String(contentsOf: bundle.url( + forResource: fileName, + withExtension: fileExtension )!, encoding: .utf8) - }() + } } diff --git a/tests/unit/Utility.swift b/tests/Shared/Utility.swift similarity index 100% rename from tests/unit/Utility.swift rename to tests/Shared/Utility.swift diff --git a/tests/Shared/XCPMApplication.swift b/tests/Shared/XCPMApplication.swift new file mode 100644 index 0000000..e96029a --- /dev/null +++ b/tests/Shared/XCPMApplication.swift @@ -0,0 +1,23 @@ +// +// XCPMApplication.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 16/10/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import XCTest + +class XCPMApplication: XCUIApplication { + public func withConfiguration(_ configuration: TestableConfiguration) { + let path = persistTestable(configuration) + self.launchArguments = ["--configuration:\(path)"] + } + + private func persistTestable(_ configuration: TestableConfiguration) -> String { + let tempDirectoryURL = NSURL.fileURL(withPath: NSTemporaryDirectory(), isDirectory: true) + let targetURL = tempDirectoryURL.appendingPathComponent("\(UUID().uuidString).json") + try! configuration.toJson().write(toFile: targetURL.path, atomically: true, encoding: .utf8) + return targetURL.path + } +} diff --git a/tests/ui/StartupTest.swift b/tests/ui/StartupTest.swift index 22008b4..0dc4c01 100644 --- a/tests/ui/StartupTest.swift +++ b/tests/ui/StartupTest.swift @@ -1,5 +1,5 @@ // -// UI_Tests.swift +// StartupTest.swift // UI Tests // // Created by Nico Verbruggen on 14/10/2022. @@ -17,14 +17,18 @@ final class StartupTest: UITestCase { override func tearDownWithError() throws {} func testApplicationCanLaunchWithTestConfigurationAndIdles() throws { - let app = XCUIApplication() - app.launchArguments = ["--configuration:working"] + let app = XCPMApplication() + app.withConfiguration(TestableConfigurations.working) app.launch() + sleep(5) } func testApplicationCanLaunchWithTestConfigurationAndThrowsAlert() throws { - let app = XCUIApplication() - app.launchArguments = ["--configuration:broken"] + var configuration = TestableConfigurations.working + configuration.filesystem["/opt/homebrew/bin/php"] = nil // PHP binary must be missing + + let app = XCPMApplication() + app.withConfiguration(configuration) app.launch() // Dialog 1: "PHP is not correctly installed" diff --git a/tests/unit/Test Files/brew/brew-services-normal.json b/tests/unit/Test Files/brew/brew-services-normal.json new file mode 100644 index 0000000..7913c7e --- /dev/null +++ b/tests/unit/Test Files/brew/brew-services-normal.json @@ -0,0 +1,173 @@ +[ + { + "name": "dnsmasq", + "service_name": "homebrew.mxcl.dnsmasq", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": "root", + "status": "none", + "file": "/Users/nicoverbruggen/Library/LaunchAgents/homebrew.mxcl.dnsmasq.plist", + "command": "/opt/homebrew/opt/dnsmasq/sbin/dnsmasq --keep-in-foreground -C /opt/homebrew/etc/dnsmasq.conf -7 /opt/homebrew/etc/dnsmasq.d,*.conf", + "working_dir": null, + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + }, + { + "name": "httpd", + "service_name": "homebrew.mxcl.httpd", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/httpd/homebrew.mxcl.httpd.plist", + "command": "/opt/homebrew/opt/httpd/bin/httpd -D FOREGROUND", + "working_dir": null, + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + }, + { + "name": "mailhog", + "service_name": "homebrew.mxcl.mailhog", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 686, + "exit_code": 0, + "user": "nicoverbruggen", + "status": "started", + "file": "/Users/nicoverbruggen/Library/LaunchAgents/homebrew.mxcl.mailhog.plist", + "command": "/opt/homebrew/opt/mailhog/bin/MailHog", + "working_dir": null, + "root_dir": null, + "log_path": "/opt/homebrew/var/log/mailhog.log", + "error_log_path": "/opt/homebrew/var/log/mailhog.log", + "interval": null, + "cron": null + }, + { + "name": "nginx", + "service_name": "homebrew.mxcl.nginx", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": "root", + "status": "none", + "file": "/Users/nicoverbruggen/Library/LaunchAgents/homebrew.mxcl.nginx.plist", + "command": "/opt/homebrew/opt/nginx/bin/nginx -g daemon off;", + "working_dir": "/opt/homebrew", + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + }, + { + "name": "php", + "service_name": "homebrew.mxcl.php", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": "root", + "status": "none", + "file": "/Users/nicoverbruggen/Library/LaunchAgents/homebrew.mxcl.php.plist", + "command": "/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "php@7.4", + "service_name": "homebrew.mxcl.php@7.4", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/php@7.4/homebrew.mxcl.php@7.4.plist", + "command": "/opt/homebrew/opt/php@7.4/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "php@8.0", + "service_name": "homebrew.mxcl.php@8.0", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/php@8.0/homebrew.mxcl.php@8.0.plist", + "command": "/opt/homebrew/opt/php@8.0/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "php@8.2", + "service_name": "homebrew.mxcl.php@8.2", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": "root", + "status": "none", + "file": "/Users/nicoverbruggen/Library/LaunchAgents/homebrew.mxcl.php@8.2.plist", + "command": "/opt/homebrew/opt/php@8.2/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "unbound", + "service_name": "homebrew.mxcl.unbound", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/unbound/homebrew.mxcl.unbound.plist", + "command": "/opt/homebrew/opt/unbound/sbin/unbound -d -c /opt/homebrew/etc/unbound/unbound.conf", + "working_dir": null, + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + } +] diff --git a/tests/unit/Test Files/brew/brew-services-sudo.json b/tests/unit/Test Files/brew/brew-services-sudo.json new file mode 100644 index 0000000..6554f3f --- /dev/null +++ b/tests/unit/Test Files/brew/brew-services-sudo.json @@ -0,0 +1,173 @@ +[ + { + "name": "dnsmasq", + "service_name": "homebrew.mxcl.dnsmasq", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 122, + "exit_code": 0, + "user": "root", + "status": "started", + "file": "/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist", + "command": "/opt/homebrew/opt/dnsmasq/sbin/dnsmasq --keep-in-foreground -C /opt/homebrew/etc/dnsmasq.conf -7 /opt/homebrew/etc/dnsmasq.d,*.conf", + "working_dir": null, + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + }, + { + "name": "httpd", + "service_name": "homebrew.mxcl.httpd", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/httpd/homebrew.mxcl.httpd.plist", + "command": "/opt/homebrew/opt/httpd/bin/httpd -D FOREGROUND", + "working_dir": null, + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + }, + { + "name": "mailhog", + "service_name": "homebrew.mxcl.mailhog", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": "root", + "status": "none", + "file": "/Library/LaunchDaemons/homebrew.mxcl.mailhog.plist", + "command": "/opt/homebrew/opt/mailhog/bin/MailHog", + "working_dir": null, + "root_dir": null, + "log_path": "/opt/homebrew/var/log/mailhog.log", + "error_log_path": "/opt/homebrew/var/log/mailhog.log", + "interval": null, + "cron": null + }, + { + "name": "nginx", + "service_name": "homebrew.mxcl.nginx", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 133, + "exit_code": 0, + "user": "root", + "status": "started", + "file": "/Library/LaunchDaemons/homebrew.mxcl.nginx.plist", + "command": "/opt/homebrew/opt/nginx/bin/nginx -g daemon off;", + "working_dir": "/opt/homebrew", + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + }, + { + "name": "php", + "service_name": "homebrew.mxcl.php", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 160, + "exit_code": 0, + "user": "root", + "status": "started", + "file": "/Library/LaunchDaemons/homebrew.mxcl.php.plist", + "command": "/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "php@7.4", + "service_name": "homebrew.mxcl.php@7.4", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/php@7.4/homebrew.mxcl.php@7.4.plist", + "command": "/opt/homebrew/opt/php@7.4/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "php@8.0", + "service_name": "homebrew.mxcl.php@8.0", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/php@8.0/homebrew.mxcl.php@8.0.plist", + "command": "/opt/homebrew/opt/php@8.0/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "php@8.2", + "service_name": "homebrew.mxcl.php@8.2", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 147, + "exit_code": 0, + "user": "root", + "status": "started", + "file": "/Library/LaunchDaemons/homebrew.mxcl.php@8.2.plist", + "command": "/opt/homebrew/opt/php@8.2/sbin/php-fpm --nodaemonize", + "working_dir": "/opt/homebrew/var", + "root_dir": null, + "log_path": null, + "error_log_path": "/opt/homebrew/var/log/php-fpm.log", + "interval": null, + "cron": null + }, + { + "name": "unbound", + "service_name": "homebrew.mxcl.unbound", + "running": false, + "loaded": false, + "schedulable": false, + "pid": null, + "exit_code": null, + "user": null, + "status": "none", + "file": "/opt/homebrew/opt/unbound/homebrew.mxcl.unbound.plist", + "command": "/opt/homebrew/opt/unbound/sbin/unbound -d -c /opt/homebrew/etc/unbound/unbound.conf", + "working_dir": null, + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + } +] diff --git a/tests/unit/Testables/TestableConfigurationTest.swift b/tests/unit/Testables/TestableConfigurationTest.swift new file mode 100644 index 0000000..b51cee7 --- /dev/null +++ b/tests/unit/Testables/TestableConfigurationTest.swift @@ -0,0 +1,21 @@ +// +// TestableConfigurationTest.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 16/10/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import XCTest + +class TestableConfigurationTest: XCTestCase { + func test_configuration_can_be_saved_as_json() async { + var configuration = TestableConfigurations.working + configuration.filesystem["/opt/homebrew/bin/php"] = nil + print(configuration.filesystem.keys) + let json = configuration.toJson() + try! json.write(toFile: "/tmp/pmc_working.json", atomically: true, encoding: .utf8) + try! json.write(toFile: "/tmp/pmc_broken.json", atomically: true, encoding: .utf8) + } +} +