mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-06 11:30:08 +02:00
✅ Improve tests
This commit is contained in:
@ -587,6 +587,7 @@
|
||||
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||
C4C8E81B276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
||||
C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
||||
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB250429B28BB800CA4492 /* MainMenuTest.swift */; };
|
||||
C4CB6E65292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||
C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||
C4CB6E67292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||
@ -915,6 +916,7 @@
|
||||
C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveFileSystem.swift; sourceTree = "<group>"; };
|
||||
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "App+ConfigWatch.swift"; sourceTree = "<group>"; };
|
||||
C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpConfigWatcher.swift; sourceTree = "<group>"; };
|
||||
C4CB250429B28BB800CA4492 /* MainMenuTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuTest.swift; sourceTree = "<group>"; };
|
||||
C4CB6E64292C362C002E9027 /* Homebrew.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
|
||||
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; };
|
||||
C4CDA892288F1A71007CE25F /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
|
||||
@ -1432,6 +1434,7 @@
|
||||
C469E702294CFDF700A82AB2 /* DomainsListTest.swift */,
|
||||
C44E985E29B23EBF0059F773 /* UpdateCheckTest.swift */,
|
||||
C4181F1028FAF9330042EA28 /* UITestCase.swift */,
|
||||
C4CB250429B28BB800CA4492 /* MainMenuTest.swift */,
|
||||
);
|
||||
path = ui;
|
||||
sourceTree = "<group>";
|
||||
@ -2455,6 +2458,7 @@
|
||||
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */,
|
||||
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */,
|
||||
C471E8DF28F9BB8F0021E251 /* PhpConfigWatcher.swift in Sources */,
|
||||
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */,
|
||||
C471E8E028F9BB8F0021E251 /* Preset.swift in Sources */,
|
||||
C471E8E128F9BB8F0021E251 /* PresetHelper.swift in Sources */,
|
||||
C471E8E228F9BB8F0021E251 /* WarningView.swift in Sources */,
|
||||
|
@ -28,10 +28,12 @@ class PhpHelper {
|
||||
Task { // Create the appropriate folders and check if the files exist
|
||||
do {
|
||||
if !FileSystem.directoryExists("~/.config/phpmon/bin") {
|
||||
try FileSystem.createDirectory(
|
||||
"~/.config/phpmon/bin",
|
||||
withIntermediateDirectories: true
|
||||
)
|
||||
Task { @MainActor in
|
||||
try FileSystem.createDirectory(
|
||||
"~/.config/phpmon/bin",
|
||||
withIntermediateDirectories: true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if FileSystem.fileExists(destination) {
|
||||
@ -59,10 +61,12 @@ class PhpHelper {
|
||||
export PATH=\(path):$PATH
|
||||
"""
|
||||
|
||||
try FileSystem.writeAtomicallyToFile(destination, content: script)
|
||||
Task { @MainActor in
|
||||
try FileSystem.writeAtomicallyToFile(destination, content: script)
|
||||
|
||||
if !FileSystem.isExecutableFile(destination) {
|
||||
try FileSystem.makeExecutable(destination)
|
||||
if !FileSystem.isExecutableFile(destination) {
|
||||
try FileSystem.makeExecutable(destination)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a symlink if the folder is not in the PATH
|
||||
|
@ -15,6 +15,88 @@ public struct TestableConfiguration: Codable {
|
||||
var commandOutput: [String: String]
|
||||
var preferenceOverrides: [PreferenceName: Bool]
|
||||
|
||||
init(
|
||||
architecture: String,
|
||||
filesystem: [String: FakeFile],
|
||||
shellOutput: [String: BatchFakeShellOutput],
|
||||
commandOutput: [String: String],
|
||||
preferenceOverrides: [PreferenceName: Bool],
|
||||
phpVersions: [VersionNumber]
|
||||
) {
|
||||
self.architecture = architecture
|
||||
self.filesystem = filesystem
|
||||
self.shellOutput = shellOutput
|
||||
self.commandOutput = commandOutput
|
||||
self.preferenceOverrides = preferenceOverrides
|
||||
|
||||
phpVersions.enumerated().forEach { (index, version) in
|
||||
self.addPhpVersion(version, primary: index == 0)
|
||||
}
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case architecture, filesystem, shellOutput, commandOutput, preferenceOverrides
|
||||
}
|
||||
|
||||
// MARK: Add PHP versions
|
||||
|
||||
private var primaryPhpVersion: VersionNumber?
|
||||
private var secondaryPhpVersions: [VersionNumber] = []
|
||||
|
||||
mutating func addPhpVersion(_ version: VersionNumber, primary: Bool) {
|
||||
if primary {
|
||||
if primaryPhpVersion != nil {
|
||||
fatalError("You cannot add multiple primary PHP versions to a testable configuration!")
|
||||
}
|
||||
primaryPhpVersion = version
|
||||
} else {
|
||||
self.secondaryPhpVersions.append(version)
|
||||
}
|
||||
|
||||
self.filesystem = self.filesystem.merging([
|
||||
"/opt/homebrew/opt/php@\(version.short)/bin/php"
|
||||
: .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php"),
|
||||
"/opt/homebrew/Cellar/php/\(version.long)/bin/php"
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
|
||||
: .fake(.text),
|
||||
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/valet-fpm.conf"
|
||||
: .fake(.text),
|
||||
"/opt/homebrew/etc/php/\(version.short)/php.ini"
|
||||
: .fake(.text),
|
||||
"/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini"
|
||||
: .fake(.text)
|
||||
]) { (_, new) in new }
|
||||
|
||||
if primary {
|
||||
self.shellOutput["ls /opt/homebrew/opt | grep php"]
|
||||
= .instant("php")
|
||||
self.filesystem["/opt/homebrew/opt/php"]
|
||||
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)")
|
||||
self.filesystem["/opt/homebrew/opt/php/bin/php"]
|
||||
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php")
|
||||
self.filesystem["/opt/homebrew/bin/php"]
|
||||
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php")
|
||||
self.commandOutput["/opt/homebrew/bin/php-config --version"]
|
||||
= version.long
|
||||
self.commandOutput["/opt/homebrew/bin/php -r echo php_ini_scanned_files();"] =
|
||||
"""
|
||||
/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini,
|
||||
"""
|
||||
} else {
|
||||
self.shellOutput["ls /opt/homebrew/opt | grep php@"] =
|
||||
BatchFakeShellOutput.instant(
|
||||
self.secondaryPhpVersions
|
||||
.map { "php@\($0.short)" }
|
||||
.joined(separator: "\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Interactions
|
||||
|
||||
func apply() {
|
||||
Log.separator()
|
||||
Log.info("USING TESTABLE CONFIGURATION...")
|
||||
@ -38,6 +120,8 @@ public struct TestableConfiguration: Codable {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Persist and load
|
||||
|
||||
func toJson(pretty: Bool = false) -> String {
|
||||
let data = try! JSONEncoder().encode(self)
|
||||
|
||||
|
@ -24,16 +24,6 @@ class TestableConfigurations {
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/bin/valet"
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/opt/php"
|
||||
: .fake(.symlink, "/opt/homebrew/Cellar/php/8.2.0"),
|
||||
"/opt/homebrew/opt/php@8.2/bin/php"
|
||||
: .fake(.symlink, "/opt/homebrew/Cellar/php/8.2.0/bin/php"),
|
||||
"/opt/homebrew/Cellar/php/8.2.0/bin/php"
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/Cellar/php/8.2.0/bin/php-config"
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/etc/php/8.2/php-fpm.d/www.conf"
|
||||
: .fake(.text),
|
||||
"~/.config/valet/config.json"
|
||||
: .fake(.text, """
|
||||
{
|
||||
@ -45,12 +35,6 @@ class TestableConfigurations {
|
||||
"loopback": "127.0.0.1"
|
||||
}
|
||||
"""),
|
||||
"/opt/homebrew/etc/php/8.2/php-fpm.d/valet-fpm.conf"
|
||||
: .fake(.text),
|
||||
"/opt/homebrew/etc/php/8.2/php.ini"
|
||||
: .fake(.text),
|
||||
"/opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini"
|
||||
: .fake(.text)
|
||||
],
|
||||
shellOutput: [
|
||||
"sysctl -n sysctl.proc_translated"
|
||||
@ -59,17 +43,6 @@ class TestableConfigurations {
|
||||
: .instant("user"),
|
||||
"which node"
|
||||
: .instant("/opt/homebrew/bin/node"),
|
||||
"php -v"
|
||||
: .instant("""
|
||||
PHP 8.2.0 (cli) (built: Dec XX 20XX XX:XX:XX) (NTS)
|
||||
Copyright (c) The PHP Group
|
||||
Zend Engine vX.X, Copyright (c) Zend Technologies
|
||||
with Zend OPcache vX.X, Copyright (c), by Zend Technologies
|
||||
"""),
|
||||
"ls /opt/homebrew/opt | grep php"
|
||||
: .instant("php"),
|
||||
"ls /opt/homebrew/opt | grep php@"
|
||||
: .instant("php@8.2"),
|
||||
"sudo /opt/homebrew/bin/brew services info dnsmasq --json"
|
||||
: .delayed(0.2, """
|
||||
[
|
||||
@ -176,16 +149,16 @@ class TestableConfigurations {
|
||||
: .instant("OK"),
|
||||
],
|
||||
commandOutput: [
|
||||
"/opt/homebrew/bin/php-config --version": "8.2.0",
|
||||
"/opt/homebrew/bin/php -r echo ini_get('memory_limit');": "512M",
|
||||
"/opt/homebrew/bin/php -r echo ini_get('upload_max_filesize');": "512M",
|
||||
"/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M",
|
||||
"/opt/homebrew/bin/php -r echo php_ini_scanned_files();"
|
||||
: """
|
||||
/opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini,
|
||||
"""
|
||||
],
|
||||
preferenceOverrides: [:]
|
||||
preferenceOverrides: [:],
|
||||
phpVersions: [
|
||||
VersionNumber(major: 8, minor: 2, patch: 0),
|
||||
VersionNumber(major: 8, minor: 1, patch: 0),
|
||||
VersionNumber(major: 8, minor: 0, patch: 0)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
50
tests/ui/MainMenuTest.swift
Normal file
50
tests/ui/MainMenuTest.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// MainMenuTest.swift
|
||||
// UI Tests
|
||||
//
|
||||
// Created by Nico Verbruggen on 03/03/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
final class MainMenuTest: UITestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
final func test_can_open_status_menu_item() throws {
|
||||
let app = launch(openMenu: true)
|
||||
|
||||
assertAllExist([
|
||||
// "Switch to PHP 8.2 (php)" should be visible since it is aliased to `php`
|
||||
app.menuItems["\("mi_php_switch".localized) 8.2 (php)"],
|
||||
// "Switch to PHP 8.1" should be the non-disabled option
|
||||
app.menuItems["\("mi_php_switch".localized) 8.1 (php@8.1)"],
|
||||
// "Switch to PHP 8.0" should be the non-disabled option
|
||||
app.menuItems["\("mi_php_switch".localized) 8.0 (php@8.0)"],
|
||||
// We should see the about and quit items
|
||||
app.menuItems["mi_about".localized],
|
||||
app.menuItems["mi_quit".localized]
|
||||
])
|
||||
|
||||
sleep(2)
|
||||
}
|
||||
|
||||
final func test_can_open_about() throws {
|
||||
let app = launch(openMenu: true)
|
||||
app.mainMenuItem(withText: "mi_about".localized).click()
|
||||
}
|
||||
|
||||
final func test_can_open_settings() throws {
|
||||
let app = launch(openMenu: true)
|
||||
app.mainMenuItem(withText: "mi_preferences".localized).click()
|
||||
}
|
||||
|
||||
final func test_can_quit_app() throws {
|
||||
let app = launch(openMenu: true)
|
||||
app.mainMenuItem(withText: "mi_quit".localized).click()
|
||||
}
|
||||
|
||||
}
|
@ -20,9 +20,7 @@ final class StartupTest: UITestCase {
|
||||
var configuration = TestableConfigurations.working
|
||||
configuration.filesystem["/opt/homebrew/bin/php"] = nil // PHP binary must be missing
|
||||
|
||||
let app = XCPMApplication()
|
||||
app.withConfiguration(configuration)
|
||||
app.launch()
|
||||
let app = launch(with: configuration)
|
||||
|
||||
// Dialog 1: "PHP is not correctly installed"
|
||||
assertAllExist([
|
||||
@ -52,9 +50,7 @@ final class StartupTest: UITestCase {
|
||||
var configuration = TestableConfigurations.working
|
||||
configuration.filesystem["/opt/homebrew/etc/php/8.2/php-fpm.d/valet-fpm.conf"] = nil
|
||||
|
||||
let app = XCPMApplication()
|
||||
app.withConfiguration(configuration)
|
||||
app.launch()
|
||||
let app = launch(with: configuration)
|
||||
|
||||
assertExists(app.staticTexts["alert.php_fpm_broken.title".localized], 3.0)
|
||||
click(app.buttons["generic.ok".localized])
|
||||
@ -64,30 +60,9 @@ final class StartupTest: UITestCase {
|
||||
var configuration = TestableConfigurations.working
|
||||
configuration.shellOutput["valet --version"] = .instant("Laravel Valet 5.0")
|
||||
|
||||
let app = XCPMApplication()
|
||||
app.withConfiguration(configuration)
|
||||
app.launch()
|
||||
let app = launch(with: configuration)
|
||||
|
||||
assertExists(app.staticTexts["startup.errors.valet_version_not_supported.title".localized], 3.0)
|
||||
click(app.buttons["generic.ok".localized])
|
||||
}
|
||||
|
||||
final func test_can_open_status_menu_item() 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
|
||||
app.statusItems.firstMatch.click()
|
||||
|
||||
assertAllExist([
|
||||
// "Switch to PHP 8.1 (php)" should be visible since it is aliased to `php`
|
||||
app.menuItems["\("mi_php_switch".localized) 8.2 (php)"],
|
||||
// We should see the about and quit items
|
||||
app.menuItems["mi_about".localized],
|
||||
app.menuItems["mi_quit".localized]
|
||||
])
|
||||
sleep(2)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
import XCTest
|
||||
|
||||
class UITestCase: XCTestCase {
|
||||
|
||||
/** Launches the app and opens the menu. */
|
||||
public func launch(
|
||||
openMenu: Bool = false,
|
||||
@ -50,7 +49,15 @@ class UITestCase: XCTestCase {
|
||||
public func click(_ element: XCUIElement) {
|
||||
element.click()
|
||||
}
|
||||
}
|
||||
|
||||
extension XCPMApplication {
|
||||
/**
|
||||
Opens a given menu item found in the menu bar's status item.
|
||||
*/
|
||||
public func mainMenuItem(withText text: String) -> XCUIElement {
|
||||
self.statusItems.firstMatch.menuItems[text].firstMatch
|
||||
}
|
||||
}
|
||||
|
||||
extension XCUIElement {
|
||||
|
Reference in New Issue
Block a user