mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 20:10:08 +02:00
✅ Localization support for in test files
This commit is contained in:
@ -136,6 +136,9 @@
|
|||||||
C44F868E2835BD8D005C353A /* phpmon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = C44F868D2835BD8D005C353A /* phpmon-config.json */; };
|
C44F868E2835BD8D005C353A /* phpmon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = C44F868D2835BD8D005C353A /* phpmon-config.json */; };
|
||||||
C450C8C628C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
C450C8C628C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
||||||
C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
||||||
|
C4570C3A28FC355300D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
|
||||||
|
C4570C3B28FC355300D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
|
||||||
|
C4570C3C28FC355400D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
|
||||||
C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */ = {isa = PBXBuildFile; fileRef = C459B4BC27F6093700E9B4B4 /* nginx-proxy.test */; };
|
C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */ = {isa = PBXBuildFile; fileRef = C459B4BC27F6093700E9B4B4 /* nginx-proxy.test */; };
|
||||||
C45E76142854A65300B4FE0C /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
C45E76142854A65300B4FE0C /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||||
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||||
@ -1813,6 +1816,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C4570C3B28FC355300D18420 /* Localizable.strings in Resources */,
|
||||||
C4E2E85528FC256B003B070C /* brew-services-sudo.json in Resources */,
|
C4E2E85528FC256B003B070C /* brew-services-sudo.json in Resources */,
|
||||||
C4E2E85928FC256B003B070C /* brew-services-normal.json in Resources */,
|
C4E2E85928FC256B003B070C /* brew-services-normal.json in Resources */,
|
||||||
C4E2E84F28FC22E4003B070C /* brew-formula.json in Resources */,
|
C4E2E84F28FC22E4003B070C /* brew-formula.json in Resources */,
|
||||||
@ -1824,6 +1828,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C4570C3A28FC355300D18420 /* Localizable.strings in Resources */,
|
||||||
C4E2E85628FC256B003B070C /* brew-services-sudo.json in Resources */,
|
C4E2E85628FC256B003B070C /* brew-services-sudo.json in Resources */,
|
||||||
C4E2E85A28FC256B003B070C /* brew-services-normal.json in Resources */,
|
C4E2E85A28FC256B003B070C /* brew-services-normal.json in Resources */,
|
||||||
C4E2E85028FC22E4003B070C /* brew-formula.json in Resources */,
|
C4E2E85028FC22E4003B070C /* brew-formula.json in Resources */,
|
||||||
@ -1835,6 +1840,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C4570C3C28FC355400D18420 /* Localizable.strings in Resources */,
|
||||||
54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
||||||
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */,
|
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */,
|
||||||
C42CFB1827DFDFDC00862737 /* nginx-site-isolated.test in Resources */,
|
C42CFB1827DFDFDC00862737 /* nginx-site-isolated.test in Resources */,
|
||||||
|
@ -12,7 +12,9 @@ extension Data {
|
|||||||
var prettyPrintedJSONString: NSString? {
|
var prettyPrintedJSONString: NSString? {
|
||||||
guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
|
guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
|
||||||
let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
|
let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
|
||||||
let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return nil }
|
let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return prettyPrintedString
|
return prettyPrintedString
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,26 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
struct Localization {
|
||||||
|
static var bundle: Bundle = {
|
||||||
|
var bundle = Bundle.main
|
||||||
|
if isRunningTests {
|
||||||
|
bundle = Bundle(identifier: "com.nicoverbruggen.phpmon.dev")
|
||||||
|
?? Bundle(identifier: "com.nicoverbruggen.phpmon")!
|
||||||
|
}
|
||||||
|
return bundle
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
var localized: String {
|
var localized: String {
|
||||||
if #available(macOS 13, *) {
|
if #available(macOS 13, *) {
|
||||||
return NSLocalizedString(
|
return NSLocalizedString(
|
||||||
self, tableName: nil, bundle: Bundle.main, value: "", comment: ""
|
self, tableName: nil, bundle: Localization.bundle, value: "", comment: ""
|
||||||
).replacingOccurrences(of: "Preferences", with: "Settings")
|
).replacingOccurrences(of: "Preferences", with: "Settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
|
return NSLocalizedString(self, tableName: nil, bundle: Localization.bundle, value: "", comment: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
var localizedForSwiftUI: LocalizedStringKey {
|
var localizedForSwiftUI: LocalizedStringKey {
|
||||||
@ -49,7 +60,7 @@ extension String {
|
|||||||
|
|
||||||
static func random(_ length: Int) -> String {
|
static func random(_ length: Int) -> String {
|
||||||
let characters = "0123456789abcdefghijklmnopqrstuvwxyz"
|
let characters = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||||
return String((0..<length).map{ _ in characters.randomElement()! })
|
return String((0..<length).map { _ in characters.randomElement()! })
|
||||||
}
|
}
|
||||||
|
|
||||||
subscript(r: Range<String.Index>) -> String {
|
subscript(r: Range<String.Index>) -> String {
|
||||||
|
@ -31,12 +31,10 @@ class App {
|
|||||||
return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String
|
return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Just the bundle name. */
|
||||||
A fake architecture.
|
static var identifier: String {
|
||||||
When set, the real machine's system architecture is not used,
|
Bundle.main.infoDictionary?["CFBundleIdentifier"] as! String
|
||||||
but this fixed value is used instead.
|
}
|
||||||
*/
|
|
||||||
static var fakeArchitecture: String?
|
|
||||||
|
|
||||||
/** The system architecture. Paths differ based on this value. */
|
/** The system architecture. Paths differ based on this value. */
|
||||||
static var architecture: String {
|
static var architecture: String {
|
||||||
@ -55,6 +53,13 @@ class App {
|
|||||||
return machine
|
return machine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A fake architecture.
|
||||||
|
When set, the real machine's system architecture is not used,
|
||||||
|
but this fixed value is used instead.
|
||||||
|
*/
|
||||||
|
static var fakeArchitecture: String?
|
||||||
|
|
||||||
// MARK: Variables
|
// MARK: Variables
|
||||||
|
|
||||||
/** Technical information about the current environment. */
|
/** Technical information about the current environment. */
|
||||||
|
@ -51,9 +51,11 @@ class ServicesManager: ObservableObject {
|
|||||||
.decode([HomebrewService].self, from: rootJson)
|
.decode([HomebrewService].self, from: rootJson)
|
||||||
.filter({ return userServiceNames.contains($0.name) })
|
.filter({ return userServiceNames.contains($0.name) })
|
||||||
|
|
||||||
ServicesManager.shared.userServices = Dictionary(
|
DispatchQueue.main.async {
|
||||||
uniqueKeysWithValues: rootServices.map { ($0.name, $0) }
|
ServicesManager.shared.userServices = Dictionary(
|
||||||
)
|
uniqueKeysWithValues: rootServices.map { ($0.name, $0) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,6 +83,12 @@
|
|||||||
"mi_xdebug_actions" = "Actions";
|
"mi_xdebug_actions" = "Actions";
|
||||||
"mi_xdebug_disable_all" = "Disable All Modes";
|
"mi_xdebug_disable_all" = "Disable All Modes";
|
||||||
|
|
||||||
|
// GENERIC
|
||||||
|
|
||||||
|
"generic.ok" = "OK";
|
||||||
|
"generic.retry" = "Retry";
|
||||||
|
"generic.notice" = "Notice";
|
||||||
|
|
||||||
// PRESET LOADING
|
// PRESET LOADING
|
||||||
|
|
||||||
"preset_help_title" = "Working with Configuration Presets";
|
"preset_help_title" = "Working with Configuration Presets";
|
||||||
|
@ -16,13 +16,6 @@ final class StartupTest: UITestCase {
|
|||||||
|
|
||||||
override func tearDownWithError() throws {}
|
override func tearDownWithError() throws {}
|
||||||
|
|
||||||
func testApplicationCanLaunchWithTestConfigurationAndIdles() throws {
|
|
||||||
let app = XCPMApplication()
|
|
||||||
app.withConfiguration(TestableConfigurations.working)
|
|
||||||
app.launch()
|
|
||||||
sleep(5)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testApplicationCanLaunchWithTestConfigurationAndThrowsAlert() throws {
|
func testApplicationCanLaunchWithTestConfigurationAndThrowsAlert() throws {
|
||||||
var configuration = TestableConfigurations.working
|
var configuration = TestableConfigurations.working
|
||||||
configuration.filesystem["/opt/homebrew/bin/php"] = nil // PHP binary must be missing
|
configuration.filesystem["/opt/homebrew/bin/php"] = nil // PHP binary must be missing
|
||||||
@ -33,25 +26,52 @@ final class StartupTest: UITestCase {
|
|||||||
|
|
||||||
// Dialog 1: "PHP is not correctly installed"
|
// Dialog 1: "PHP is not correctly installed"
|
||||||
assertAllExist([
|
assertAllExist([
|
||||||
app.dialogs["Notice"],
|
app.dialogs["generic.notice".localized],
|
||||||
app.staticTexts["PHP is not correctly installed"],
|
app.staticTexts["startup.errors.php_binary.title".localized],
|
||||||
app.buttons["OK"],
|
app.buttons["generic.ok".localized],
|
||||||
])
|
])
|
||||||
click(app.buttons["OK"])
|
click(app.buttons["generic.ok".localized])
|
||||||
|
|
||||||
// Dialog 2: PHP Monitor failed to start
|
// Dialog 2: PHP Monitor failed to start
|
||||||
assertAllExist([
|
assertAllExist([
|
||||||
app.dialogs["Notice"],
|
app.dialogs["generic.notice".localized],
|
||||||
app.staticTexts["PHP Monitor cannot start due to a problem with your system configuration"],
|
app.staticTexts["alert.cannot_start.title".localized],
|
||||||
app.buttons["Retry"],
|
app.buttons["alert.cannot_start.retry".localized],
|
||||||
app.buttons["Quit"]
|
app.buttons["alert.cannot_start.close".localized]
|
||||||
])
|
])
|
||||||
click(app.buttons["Retry"])
|
click(app.buttons["alert.cannot_start.retry".localized])
|
||||||
|
|
||||||
// Dialog 1 again
|
// Dialog 1 again
|
||||||
assertExists(app.staticTexts["PHP is not correctly installed"])
|
assertExists(app.staticTexts["startup.errors.php_binary.title".localized])
|
||||||
|
|
||||||
// At this point, we can terminate the test
|
// At this point, we can terminate the test
|
||||||
app.terminate()
|
app.terminate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testApplicationCanWarnAboutPhpFpmIssue() throws {
|
||||||
|
var configuration = TestableConfigurations.working
|
||||||
|
configuration.filesystem["/opt/homebrew/etc/php/8.1/php-fpm.d/valet-fpm.conf"] = nil
|
||||||
|
|
||||||
|
let app = XCPMApplication()
|
||||||
|
app.withConfiguration(configuration)
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
assertExists(app.staticTexts["alert.php_fpm_broken.title".localized], 3.0)
|
||||||
|
click(app.buttons["generic.ok".localized])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testApplicationCanLaunchWithTestConfigurationAndCanClickMenuItem() throws {
|
||||||
|
let app = XCPMApplication()
|
||||||
|
app.withConfiguration(TestableConfigurations.working)
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Note: If this fails here, make sure the menu bar item can be displayed
|
||||||
|
// If you use Bartender or something like this, this item may be hidden and tests will fail
|
||||||
|
let statusBarItem = app.statusItems.firstMatch
|
||||||
|
statusBarItem.click()
|
||||||
|
assertAllExist([
|
||||||
|
app.menuItems["mi_about".localized],
|
||||||
|
app.menuItems["mi_quit".localized]
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user