mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-11-07 05:10:06 +01:00
♻️ Migrate more tests to Swift Testing
This commit is contained in:
@@ -1361,6 +1361,11 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */,
|
||||
C4F780AD25D80B37000DBC97 /* PhpExtensionTest.swift */,
|
||||
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
|
||||
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
|
||||
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
||||
C456A0D02AA6175D0080144F /* Config */,
|
||||
);
|
||||
path = Parsers;
|
||||
sourceTree = "<group>";
|
||||
@@ -2188,11 +2193,6 @@
|
||||
C4C1019727C65A11001FACC2 /* Parsers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C456A0D02AA6175D0080144F /* Config */,
|
||||
C4F780AD25D80B37000DBC97 /* PhpExtensionTest.swift */,
|
||||
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
|
||||
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
|
||||
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
||||
C40934AA298EEDA900D25014 /* CaskFileParserTest.swift */,
|
||||
C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */,
|
||||
C4F520662AF03791006787F2 /* ExtensionEnumeratorTest.swift */,
|
||||
|
||||
@@ -26,34 +26,34 @@ struct Constants {
|
||||
be displayed. This is based on an appropriate launch time on a
|
||||
basic M1 Apple chip, with some margin for slower Intel chips.
|
||||
*/
|
||||
static let SlowBootThresholdInterval: TimeInterval = 30.0
|
||||
static let SlowBootThresholdInterval: TimeInterval = .seconds(30)
|
||||
|
||||
/**
|
||||
The interval between automatic background update checks.
|
||||
*/
|
||||
static let AutomaticUpdateCheckInterval: TimeInterval = 60.0 * 60 * 24 // 24 hours
|
||||
static let AutomaticUpdateCheckInterval: TimeInterval = .hours(24)
|
||||
|
||||
/**
|
||||
The minimum interval that must pass before allowing another
|
||||
automatic update check. This prevents excessive checking
|
||||
on frequent app restarts (due to crashes or bad config).
|
||||
*/
|
||||
static let MinimumUpdateCheckInterval: TimeInterval = 60.0 * 60 // 60 minutes
|
||||
static let MinimumUpdateCheckInterval: TimeInterval = .minutes(60)
|
||||
|
||||
/**
|
||||
Retry intervals for failed automatic update checks.
|
||||
Uses exponential backoff before falling back to normal schedule.
|
||||
*/
|
||||
static let UpdateCheckRetryIntervals: [TimeInterval] = [
|
||||
60 * 5, // 5 minutes
|
||||
60 * 15, // 15 minutes
|
||||
60 * 60, // 1 hour
|
||||
60 * 60 * 3 // 3 hours (final attempt)
|
||||
.minutes(5),
|
||||
.minutes(15),
|
||||
.hours(1),
|
||||
.hours(3)
|
||||
]
|
||||
|
||||
/**
|
||||
PHP Monitor supplies a hardcoded list of PHP packages in its own
|
||||
PHP Version Manager.
|
||||
PHP Version Manager.
|
||||
|
||||
This hardcoded list will expire and will need to be modified when
|
||||
the cutoff date occurs, which is when the `php` formula will
|
||||
@@ -62,8 +62,12 @@ struct Constants {
|
||||
If users launch an older version of the app, then a warning
|
||||
will be displayed to let them know that certain operations
|
||||
will not work correctly and that they need to update their app.
|
||||
|
||||
The cutoff date is always a few days after GA of the latest
|
||||
release, as it often takes a while for Homebrew to make the
|
||||
new release available and not everyone uses a separate tap.
|
||||
*/
|
||||
static let PhpFormulaeCutoffDate = "2025-11-30" // YYYY-MM-DD
|
||||
static let PhpFormulaeCutoffDate = "2025-11-20" // YYYY-MM-DD
|
||||
|
||||
/**
|
||||
* The PHP versions that are considered pre-release versions.
|
||||
@@ -72,7 +76,8 @@ struct Constants {
|
||||
*/
|
||||
static var ExperimentalPhpVersions: Set<String> {
|
||||
let releaseDates = [
|
||||
"8.5": Date.fromString(Self.PhpFormulaeCutoffDate),
|
||||
// "8.6": Date.fromString("2026-11-30"), // TBD
|
||||
"8.5": Date.fromString(PhpFormulaeCutoffDate),
|
||||
"8.4": Date.fromString("2024-11-22")
|
||||
]
|
||||
|
||||
@@ -108,6 +113,7 @@ struct Constants {
|
||||
"7.0", "7.1", "7.2", "7.3", "7.4",
|
||||
"8.0", "8.1", "8.2", "8.3", "8.4",
|
||||
"8.5" // DEV
|
||||
// "8.6" // TBD
|
||||
]
|
||||
|
||||
/**
|
||||
@@ -130,48 +136,28 @@ struct Constants {
|
||||
"7.1", "7.2", "7.3", "7.4",
|
||||
"8.0", "8.1", "8.2", "8.3", "8.4",
|
||||
"8.5" // DEV
|
||||
// "8.6" // TBD
|
||||
]
|
||||
]
|
||||
|
||||
struct Urls {
|
||||
|
||||
// phpmon.app URLs (these are aliased to redirect correctly)
|
||||
static let DonationPage = url("https://phpmon.app/sponsor")
|
||||
|
||||
static let DonationPage = URL(
|
||||
string: "https://phpmon.app/sponsor"
|
||||
)!
|
||||
static let FrequentlyAskedQuestions = url("https://phpmon.app/faq")
|
||||
|
||||
static let FrequentlyAskedQuestions = URL(
|
||||
string: "https://phpmon.app/faq"
|
||||
)!
|
||||
static let WikiPhpUnavailable = url("https://phpmon.app/php-unavailable")
|
||||
|
||||
static let WikiPhpUnavailable = URL(
|
||||
string: "https://phpmon.app/php-unavailable"
|
||||
)!
|
||||
static let WikiPhpUpgrade = url("https://phpmon.app/php-upgrade")
|
||||
|
||||
static let WikiPhpUpgrade = URL(
|
||||
string: "https://phpmon.app/php-upgrade"
|
||||
)!
|
||||
static let DonationPayment = url("https://phpmon.app/sponsor/now")
|
||||
|
||||
static let DonationPayment = URL(
|
||||
string: "https://phpmon.app/sponsor/now"
|
||||
)!
|
||||
|
||||
static let EarlyAccessChangelog = URL(
|
||||
string: "https://phpmon.app/early-access/release-notes"
|
||||
)!
|
||||
static let EarlyAccessChangelog = url("https://phpmon.app/early-access/release-notes")
|
||||
|
||||
// API endpoints (via api.phpmon.app)
|
||||
|
||||
static let UpdateCheckEndpoint = URL(
|
||||
string: "https://api.phpmon.app/api/v1/update-check"
|
||||
)!
|
||||
static let UpdateCheckEndpoint = url("https://api.phpmon.app/api/v1/update-check")
|
||||
|
||||
// GitHub URLs (do not alias these)
|
||||
|
||||
static let GitHubReleases = URL(
|
||||
string: "https://github.com/nicoverbruggen/phpmon/releases"
|
||||
)!
|
||||
static let GitHubReleases = url("https://github.com/nicoverbruggen/phpmon/releases")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ func delay(seconds: Double) async {
|
||||
try! await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
|
||||
}
|
||||
|
||||
/** A simpler way to initialize a fixed, valid URL. */
|
||||
/**
|
||||
A simpler way to initialize a fixed, valid URL.
|
||||
*/
|
||||
func url(_ string: String) -> URL {
|
||||
return URL(string: string)!
|
||||
}
|
||||
|
||||
@@ -9,7 +9,14 @@
|
||||
import Foundation
|
||||
|
||||
extension TimeInterval {
|
||||
public static func minutes(_ amount: Int) -> TimeInterval {
|
||||
return Double(amount * 60)
|
||||
static func seconds(_ value: Double) -> TimeInterval { value }
|
||||
static func minutes(_ value: Double) -> TimeInterval { value * 60 }
|
||||
static func hours(_ value: Double) -> TimeInterval { value * 3600 }
|
||||
static func days(_ value: Double) -> TimeInterval { value * 86400 }
|
||||
}
|
||||
|
||||
extension Date {
|
||||
func adding(_ interval: TimeInterval) -> Date {
|
||||
return self.addingTimeInterval(interval)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
//
|
||||
// BytePhpPreferenceTest.swift
|
||||
// Unit Tests
|
||||
//
|
||||
// Created by Nico Verbruggen on 04/09/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
class BytePhpPreferenceTest: XCTestCase {
|
||||
|
||||
func test_can_extract_memory_value() throws {
|
||||
let pref = BytePhpPreference(key: "memory_limit")
|
||||
|
||||
XCTAssertEqual(pref.internalValue, "512M")
|
||||
XCTAssertEqual(pref.unit, .megabyte)
|
||||
XCTAssertEqual(pref.value, 512)
|
||||
}
|
||||
|
||||
func test_can_parse_all_kinds_of_values() throws {
|
||||
var (unit, value) = BytePhpPreference.readFrom(internalValue: "1G")!
|
||||
XCTAssertEqual(unit, .gigabyte)
|
||||
XCTAssertEqual(value, 1)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "256M")!
|
||||
XCTAssertEqual(unit, .megabyte)
|
||||
XCTAssertEqual(value, 256)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "512K")!
|
||||
XCTAssertEqual(unit, .kilobyte)
|
||||
XCTAssertEqual(value, 512)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "1024")!
|
||||
XCTAssertEqual(unit, .kilobyte)
|
||||
XCTAssertEqual(value, 1024)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "-1")!
|
||||
XCTAssertEqual(unit, .kilobyte)
|
||||
XCTAssertEqual(value, -1)
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
//
|
||||
// NginxConfigurationTest.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 29/11/2021.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
class NginxConfigurationTest: XCTestCase {
|
||||
|
||||
// MARK: - Test Files
|
||||
|
||||
static var regularUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "nginx-site", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var isolatedUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "nginx-site-isolated", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var proxyUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "nginx-proxy", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var secureProxyUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "nginx-secure-proxy", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var customTldProxyUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "nginx-secure-proxy-custom-tld", withExtension: "test")!
|
||||
}
|
||||
|
||||
// MARK: - Tests
|
||||
|
||||
func test_can_determine_site_name_and_tld() throws {
|
||||
XCTAssertEqual(
|
||||
"nginx-site",
|
||||
NginxConfigurationFile.from(filePath: NginxConfigurationTest.regularUrl.path)?.domain
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"test",
|
||||
NginxConfigurationFile.from(filePath: NginxConfigurationTest.regularUrl.path)?.tld
|
||||
)
|
||||
}
|
||||
|
||||
func test_can_determine_isolation() throws {
|
||||
XCTAssertNil(
|
||||
NginxConfigurationFile.from(filePath: NginxConfigurationTest.regularUrl.path)?.isolatedVersion
|
||||
)
|
||||
|
||||
XCTAssertEqual(
|
||||
"8.1",
|
||||
NginxConfigurationFile.from(filePath: NginxConfigurationTest.isolatedUrl.path)?.isolatedVersion
|
||||
)
|
||||
}
|
||||
|
||||
func test_can_determine_proxy() throws {
|
||||
let proxied = NginxConfigurationFile.from(filePath: NginxConfigurationTest.proxyUrl.path)!
|
||||
XCTAssertTrue(proxied.contents.contains("# valet stub: proxy.valet.conf"))
|
||||
XCTAssertEqual("http://127.0.0.1:90", proxied.proxy)
|
||||
|
||||
let normal = NginxConfigurationFile.from(filePath: NginxConfigurationTest.regularUrl.path)!
|
||||
XCTAssertFalse(normal.contents.contains("# valet stub: proxy.valet.conf"))
|
||||
XCTAssertEqual(nil, normal.proxy)
|
||||
}
|
||||
|
||||
func test_can_determine_secured_proxy() throws {
|
||||
let proxied = NginxConfigurationFile.from(filePath: NginxConfigurationTest.secureProxyUrl.path)!
|
||||
XCTAssertTrue(proxied.contents.contains("# valet stub: secure.proxy.valet.conf"))
|
||||
XCTAssertEqual("http://127.0.0.1:90", proxied.proxy)
|
||||
}
|
||||
|
||||
func test_can_determine_proxy_with_custom_tld() throws {
|
||||
let proxied = NginxConfigurationFile.from(filePath: NginxConfigurationTest.customTldProxyUrl.path)!
|
||||
XCTAssertTrue(proxied.contents.contains("# valet stub: secure.proxy.valet.conf"))
|
||||
XCTAssertEqual("http://localhost:8080", proxied.proxy)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
//
|
||||
// ExtensionParserTest.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 13/02/2021.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
class PhpExtensionTest: XCTestCase {
|
||||
|
||||
static var phpIniFileUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "php", withExtension: "ini")!
|
||||
}
|
||||
|
||||
func test_can_load_extension() throws {
|
||||
let extensions = PhpExtension.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
XCTAssertGreaterThan(extensions.count, 0)
|
||||
}
|
||||
|
||||
func test_extension_name_is_correct() throws {
|
||||
let extensions = PhpExtension.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
let extensionNames = extensions.map { (ext) -> String in
|
||||
return ext.name
|
||||
}
|
||||
|
||||
// These 6 should be found
|
||||
XCTAssertTrue(extensionNames.contains("xdebug"))
|
||||
XCTAssertTrue(extensionNames.contains("imagick"))
|
||||
XCTAssertTrue(extensionNames.contains("sodium-next"))
|
||||
XCTAssertTrue(extensionNames.contains("opcache"))
|
||||
XCTAssertTrue(extensionNames.contains("yaml"))
|
||||
XCTAssertTrue(extensionNames.contains("custom"))
|
||||
|
||||
XCTAssertFalse(extensionNames.contains("fake"))
|
||||
XCTAssertFalse(extensionNames.contains("nice"))
|
||||
}
|
||||
|
||||
func test_extension_status_is_correct() throws {
|
||||
let extensions = PhpExtension.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
// xdebug should be enabled
|
||||
XCTAssertEqual(extensions[0].enabled, true)
|
||||
|
||||
// imagick should be disabled
|
||||
XCTAssertEqual(extensions[1].enabled, false)
|
||||
}
|
||||
|
||||
func test_toggle_works_as_expected() async throws {
|
||||
let destination = Utility.copyToTemporaryFile(resourceName: "php", fileExtension: "ini")!
|
||||
let extensions = PhpExtension.from(filePath: destination.path)
|
||||
XCTAssertEqual(extensions.count, 6)
|
||||
|
||||
// Try to disable xdebug (should be detected first)!
|
||||
let xdebug = extensions.first!
|
||||
XCTAssertTrue(xdebug.name == "xdebug")
|
||||
XCTAssertEqual(xdebug.enabled, true)
|
||||
await xdebug.toggle()
|
||||
XCTAssertEqual(xdebug.enabled, false)
|
||||
|
||||
// Check if the file contains the appropriate data
|
||||
let file = try! String(contentsOf: destination, encoding: .utf8)
|
||||
XCTAssertTrue(file.contains("; zend_extension=\"xdebug.so\""))
|
||||
|
||||
// Make sure if we load the data again, it's disabled
|
||||
XCTAssertEqual(PhpExtension.from(filePath: destination.path).first!.enabled, false)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
//
|
||||
// ValetRcTest.swift
|
||||
// Unit Tests
|
||||
//
|
||||
// Created by Nico Verbruggen on 20/01/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
class ValetRcTest: XCTestCase {
|
||||
|
||||
// MARK: - Test Files
|
||||
|
||||
static var validPath: URL {
|
||||
return Bundle(for: Self.self)
|
||||
.url(forResource: "valetrc", withExtension: "valid")!
|
||||
}
|
||||
|
||||
static var brokenPath: URL {
|
||||
return Bundle(for: Self.self)
|
||||
.url(forResource: "valetrc", withExtension: "broken")!
|
||||
}
|
||||
|
||||
// MARK: - Tests
|
||||
|
||||
func test_can_extract_fields_from_valetrc_file() throws {
|
||||
let fakeFile = RCFile.fromPath("/Users/fake/file.rc")
|
||||
XCTAssertNil(fakeFile)
|
||||
|
||||
// Can parse the file
|
||||
let validFile = RCFile.fromPath(ValetRcTest.validPath.path)
|
||||
XCTAssertNotNil(validFile)
|
||||
|
||||
let fields = validFile!.fields
|
||||
|
||||
// Correctly parses and trims (and omits double quotes) per line
|
||||
XCTAssertEqual(fields["PHP"], "php@8.2")
|
||||
XCTAssertEqual(fields["OTHER"], "thing")
|
||||
XCTAssertEqual(fields["PHPMON_WATCH"], "true")
|
||||
XCTAssertEqual(fields["SYNTAX"], "variable")
|
||||
|
||||
// Ignores entries prefixed with #
|
||||
XCTAssertTrue(!fields.keys.contains("#PHP"))
|
||||
|
||||
// Ignores invalid lines
|
||||
XCTAssertTrue(!fields.keys.contains("OOF"))
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,14 @@
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
@Suite("Api")
|
||||
struct TestableApiTest {
|
||||
|
||||
@Test
|
||||
func createFakeApi() {
|
||||
@Test func createFakeApi() {
|
||||
let api = TestableApi(responses: [
|
||||
url("https://api.phpmon.test"): FakeApiResponse(statusCode: 200, headers: [:], text: "{\"success\": true}")
|
||||
url("https://api.phpmon.test"): FakeApiResponse(
|
||||
statusCode: 200,
|
||||
headers: [:],
|
||||
text: "{\"success\": true}"
|
||||
)
|
||||
])
|
||||
|
||||
#expect(api.hasResponse(for: url("https://api.phpmon.test")) == true)
|
||||
@@ -25,5 +26,4 @@ struct TestableApiTest {
|
||||
#expect(response.statusCode == 200)
|
||||
#expect(response.text.contains("success"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
|
||||
import Testing
|
||||
|
||||
@Suite("Commands")
|
||||
struct CommandTest {
|
||||
|
||||
@Test
|
||||
func determinePhpVersion() {
|
||||
@Test func determinePhpVersion() {
|
||||
let version = Command.execute(
|
||||
path: Paths.php,
|
||||
arguments: ["-v"],
|
||||
@@ -24,5 +21,4 @@ struct CommandTest {
|
||||
#expect(version.contains("built"))
|
||||
#expect(version.contains("Zend"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
import Testing
|
||||
|
||||
@Suite("Integration")
|
||||
struct PackagistTest {
|
||||
@Test func canRetrieveLaravelValetVersion() async {
|
||||
let packageToCheck = "laravel/valet"
|
||||
|
||||
41
tests/unit/_ST/Parsers/Config/BytePhpPreferenceTest.swift
Normal file
41
tests/unit/_ST/Parsers/Config/BytePhpPreferenceTest.swift
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// BytePhpPreferenceTest.swift
|
||||
// Unit Tests
|
||||
//
|
||||
// Created by Nico Verbruggen on 04/09/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Testing
|
||||
|
||||
struct BytePhpPreferenceTest {
|
||||
@Test func test_can_extract_memory_value() throws {
|
||||
let pref = BytePhpPreference(key: "memory_limit")
|
||||
|
||||
#expect(pref.internalValue == "512M")
|
||||
#expect(pref.unit == .megabyte)
|
||||
#expect(pref.value == 512)
|
||||
}
|
||||
|
||||
@Test func test_can_parse_all_kinds_of_values() throws {
|
||||
var (unit, value) = BytePhpPreference.readFrom(internalValue: "1G")!
|
||||
#expect(unit == .gigabyte)
|
||||
#expect(value == 1)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "256M")!
|
||||
#expect(unit == .megabyte)
|
||||
#expect(value == 256)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "512K")!
|
||||
#expect(unit == .kilobyte)
|
||||
#expect(value == 512)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "1024")!
|
||||
#expect(unit == .kilobyte)
|
||||
#expect(value == 1024)
|
||||
|
||||
(unit, value) = BytePhpPreference.readFrom(internalValue: "-1")!
|
||||
#expect(unit == .kilobyte)
|
||||
#expect(value == -1)
|
||||
}
|
||||
}
|
||||
@@ -6,41 +6,41 @@
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
class PhpConfigurationFileTest: XCTestCase {
|
||||
class PhpConfigurationFileTest {
|
||||
|
||||
static var phpIniFileUrl: URL {
|
||||
return Bundle(for: Self.self).url(forResource: "php", withExtension: "ini")!
|
||||
return TestBundle.url(forResource: "php", withExtension: "ini")!
|
||||
}
|
||||
|
||||
func test_can_load_extension() throws {
|
||||
@Test func test_can_load_extension() throws {
|
||||
let iniFile = PhpConfigurationFile.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
#expect(iniFile != nil)
|
||||
#expect(!iniFile!.extensions.isEmpty)
|
||||
}
|
||||
|
||||
@Test func test_can_check_key_existence() throws {
|
||||
let iniFile = PhpConfigurationFile.from(filePath: Self.phpIniFileUrl.path)!
|
||||
|
||||
XCTAssertNotNil(iniFile)
|
||||
|
||||
XCTAssertGreaterThan(iniFile.extensions.count, 0)
|
||||
#expect(iniFile.has(key: "error_reporting"))
|
||||
#expect(iniFile.has(key: "display_errors"))
|
||||
#expect(false == iniFile.has(key: "my_unknown_key"))
|
||||
}
|
||||
|
||||
func test_can_check_key_existence() throws {
|
||||
@Test func test_can_check_key_value() throws {
|
||||
let iniFile = PhpConfigurationFile.from(filePath: Self.phpIniFileUrl.path)!
|
||||
|
||||
XCTAssertTrue(iniFile.has(key: "error_reporting"))
|
||||
XCTAssertTrue(iniFile.has(key: "display_errors"))
|
||||
XCTAssertFalse(iniFile.has(key: "my_unknown_key"))
|
||||
#expect(iniFile.get(for: "error_reporting") != nil)
|
||||
#expect(iniFile.get(for: "error_reporting") == "E_ALL")
|
||||
|
||||
#expect(iniFile.get(for: "display_errors") != nil)
|
||||
#expect(iniFile.get(for: "display_errors") == "On")
|
||||
}
|
||||
|
||||
func test_can_check_key_value() throws {
|
||||
let iniFile = PhpConfigurationFile.from(filePath: Self.phpIniFileUrl.path)!
|
||||
|
||||
XCTAssertNotNil(iniFile.get(for: "error_reporting"))
|
||||
XCTAssert(iniFile.get(for: "error_reporting") == "E_ALL")
|
||||
|
||||
XCTAssertNotNil(iniFile.get(for: "display_errors"))
|
||||
XCTAssert(iniFile.get(for: "display_errors") == "On")
|
||||
}
|
||||
|
||||
func test_can_customize_configuration_value() throws {
|
||||
@Test func test_can_customize_configuration_value() throws {
|
||||
let destination = Utility
|
||||
.copyToTemporaryFile(resourceName: "php", fileExtension: "ini")!
|
||||
|
||||
@@ -48,15 +48,15 @@ class PhpConfigurationFileTest: XCTestCase {
|
||||
.from(filePath: destination.path)!
|
||||
|
||||
// 0. Verify the original value
|
||||
XCTAssertEqual(configurationFile.get(for: "error_reporting"), "E_ALL")
|
||||
#expect(configurationFile.get(for: "error_reporting") == "E_ALL")
|
||||
|
||||
// 1. Change the value
|
||||
try! configurationFile.replace(
|
||||
key: "error_reporting",
|
||||
value: "E_ALL & ~E_DEPRECATED & ~E_STRICT"
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configurationFile.get(for: "error_reporting"),
|
||||
#expect(
|
||||
configurationFile.get(for: "error_reporting") ==
|
||||
"E_ALL & ~E_DEPRECATED & ~E_STRICT"
|
||||
)
|
||||
|
||||
@@ -65,20 +65,14 @@ class PhpConfigurationFileTest: XCTestCase {
|
||||
key: "error_reporting",
|
||||
value: "error_reporting"
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configurationFile.get(for: "error_reporting"),
|
||||
"error_reporting"
|
||||
)
|
||||
#expect(configurationFile.get(for: "error_reporting") == "error_reporting")
|
||||
|
||||
// 3. Verify subsequent saves weren't broken
|
||||
try! configurationFile.replace(
|
||||
key: "error_reporting",
|
||||
value: "E_ALL"
|
||||
)
|
||||
XCTAssertEqual(
|
||||
configurationFile.get(for: "error_reporting"),
|
||||
"E_ALL"
|
||||
)
|
||||
#expect(configurationFile.get(for: "error_reporting") == "E_ALL")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,53 +6,54 @@
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
class HomebrewPackageTest: XCTestCase {
|
||||
struct HomebrewPackageTest {
|
||||
|
||||
// - MARK: SYNTHETIC TESTS
|
||||
|
||||
static var jsonBrewFile: URL {
|
||||
return Bundle(for: Self.self)
|
||||
return TestBundle
|
||||
.url(forResource: "brew-formula", withExtension: "json")!
|
||||
}
|
||||
|
||||
func test_can_load_extension_json() throws {
|
||||
static var jsonBrewServicesFile: URL {
|
||||
return TestBundle
|
||||
.url(forResource: "brew-services", withExtension: "json")!
|
||||
}
|
||||
|
||||
@Test func test_can_load_extension_json() throws {
|
||||
let json = try! String(contentsOf: Self.jsonBrewFile, encoding: .utf8)
|
||||
let package = try! JSONDecoder().decode(
|
||||
[HomebrewPackage].self, from: json.data(using: .utf8)!
|
||||
).first!
|
||||
|
||||
XCTAssertEqual(package.full_name, "php")
|
||||
XCTAssertEqual(package.aliases.first!, "php@8.4")
|
||||
XCTAssertEqual(package.installed.contains(where: { installed in
|
||||
#expect(package.full_name == "php")
|
||||
#expect(package.aliases.first! == "php@8.4")
|
||||
#expect(package.installed.contains(where: { installed in
|
||||
installed.version.starts(with: "8.4")
|
||||
}), true)
|
||||
}) == true)
|
||||
}
|
||||
|
||||
static var jsonBrewServicesFile: URL {
|
||||
return Bundle(for: Self.self)
|
||||
.url(forResource: "brew-services", withExtension: "json")!
|
||||
}
|
||||
|
||||
func test_can_parse_services_json() throws {
|
||||
@Test func test_can_parse_services_json() throws {
|
||||
let json = try! String(contentsOf: Self.jsonBrewServicesFile, encoding: .utf8)
|
||||
let services = try! JSONDecoder().decode(
|
||||
[HomebrewService].self, from: json.data(using: .utf8)!
|
||||
)
|
||||
|
||||
XCTAssertGreaterThan(services.count, 0)
|
||||
XCTAssertEqual(services.first?.name, "dnsmasq")
|
||||
XCTAssertEqual(services.first?.service_name, "homebrew.mxcl.dnsmasq")
|
||||
#expect(!services.isEmpty)
|
||||
#expect(services.first?.name == "dnsmasq")
|
||||
#expect(services.first?.service_name == "homebrew.mxcl.dnsmasq")
|
||||
}
|
||||
|
||||
/*
|
||||
// - MARK: LIVE TESTS
|
||||
|
||||
/// This test requires that you have a valid Homebrew installation set up,
|
||||
/// and requires the Valet services to be installed: php, nginx and dnsmasq.
|
||||
/// If this test fails, there is an issue with your Homebrew installation
|
||||
/// or the JSON API of the Homebrew output may have changed.
|
||||
@Test(.disabled("Uses system command; enable at your own risk"))
|
||||
func test_can_parse_services_json_from_cli_output() async throws {
|
||||
ActiveShell.useSystem()
|
||||
|
||||
@@ -65,17 +66,19 @@ class HomebrewPackageTest: XCTestCase {
|
||||
return ["php", "nginx", "dnsmasq"].contains(service.name)
|
||||
})
|
||||
|
||||
XCTAssertTrue(services.contains(where: {$0.name == "php"}))
|
||||
XCTAssertTrue(services.contains(where: {$0.name == "nginx"}))
|
||||
XCTAssertTrue(services.contains(where: {$0.name == "dnsmasq"}))
|
||||
XCTAssertEqual(services.count, 3)
|
||||
#expect(services.contains(where: {$0.name == "php"}))
|
||||
#expect(services.contains(where: {$0.name == "nginx"}))
|
||||
#expect(services.contains(where: {$0.name == "dnsmasq"}))
|
||||
#expect(services.count == 3)
|
||||
}
|
||||
|
||||
/// This test requires that you have a valid Homebrew installation set up,
|
||||
/// and requires the `php` formula to be installed.
|
||||
/// If this test fails, there is an issue with your Homebrew installation
|
||||
/// or the JSON API of the Homebrew output may have changed.
|
||||
@Test(.disabled("Uses system command; enable at your own risk"))
|
||||
func test_can_load_extension_json_from_cli_output() async throws {
|
||||
|
||||
ActiveShell.useSystem()
|
||||
|
||||
let package = try! JSONDecoder().decode(
|
||||
@@ -83,7 +86,6 @@ class HomebrewPackageTest: XCTestCase {
|
||||
from: await Shell.pipe("\(Paths.brew) info php --json").out.data(using: .utf8)!
|
||||
).first!
|
||||
|
||||
XCTAssertTrue(package.name == "php")
|
||||
#expect(package.full_name == "php")
|
||||
}
|
||||
*/
|
||||
}
|
||||
70
tests/unit/_ST/Parsers/NginxConfigurationTest.swift
Normal file
70
tests/unit/_ST/Parsers/NginxConfigurationTest.swift
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// NginxConfigurationTest.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 29/11/2021.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
struct NginxConfigurationTest {
|
||||
|
||||
// MARK: - Test Files
|
||||
|
||||
static var regularUrl: URL {
|
||||
TestBundle.url(forResource: "nginx-site", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var isolatedUrl: URL {
|
||||
TestBundle.url(forResource: "nginx-site-isolated", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var proxyUrl: URL {
|
||||
TestBundle.url(forResource: "nginx-proxy", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var secureProxyUrl: URL {
|
||||
TestBundle.url(forResource: "nginx-secure-proxy", withExtension: "test")!
|
||||
}
|
||||
|
||||
static var customTldProxyUrl: URL {
|
||||
TestBundle.url(forResource: "nginx-secure-proxy-custom-tld", withExtension: "test")!
|
||||
}
|
||||
|
||||
// MARK: - Tests
|
||||
|
||||
@Test func test_can_determine_site_name_and_tld() throws {
|
||||
#expect("nginx-site" == NginxConfigurationFile.from(filePath: Self.regularUrl.path)?.domain)
|
||||
#expect("test" == NginxConfigurationFile.from(filePath: Self.regularUrl.path)?.tld)
|
||||
}
|
||||
|
||||
@Test func test_can_determine_isolation() throws {
|
||||
#expect(nil == NginxConfigurationFile.from(filePath: Self.regularUrl.path)?.isolatedVersion)
|
||||
#expect("8.1" == NginxConfigurationFile.from(filePath: Self.isolatedUrl.path)?.isolatedVersion)
|
||||
}
|
||||
|
||||
@Test func test_can_determine_proxy() throws {
|
||||
let proxied = NginxConfigurationFile.from(filePath: Self.proxyUrl.path)!
|
||||
#expect(proxied.contents.contains("# valet stub: proxy.valet.conf"))
|
||||
#expect("http://127.0.0.1:90" == proxied.proxy)
|
||||
|
||||
let normal = NginxConfigurationFile.from(filePath: Self.regularUrl.path)!
|
||||
#expect(false == normal.contents.contains("# valet stub: proxy.valet.conf"))
|
||||
#expect(nil == normal.proxy)
|
||||
}
|
||||
|
||||
@Test func test_can_determine_secured_proxy() throws {
|
||||
let proxied = NginxConfigurationFile.from(filePath: Self.secureProxyUrl.path)!
|
||||
#expect(proxied.contents.contains("# valet stub: secure.proxy.valet.conf"))
|
||||
#expect("http://127.0.0.1:90" == proxied.proxy)
|
||||
}
|
||||
|
||||
@Test func test_can_determine_proxy_with_custom_tld() throws {
|
||||
let proxied = NginxConfigurationFile.from(filePath: Self.customTldProxyUrl.path)!
|
||||
#expect(proxied.contents.contains("# valet stub: secure.proxy.valet.conf"))
|
||||
#expect("http://localhost:8080" == proxied.proxy)
|
||||
}
|
||||
|
||||
}
|
||||
71
tests/unit/_ST/Parsers/PhpExtensionTest.swift
Normal file
71
tests/unit/_ST/Parsers/PhpExtensionTest.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// ExtensionParserTest.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 13/02/2021.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
struct PhpExtensionTest {
|
||||
static var phpIniFileUrl: URL {
|
||||
return TestBundle.url(forResource: "php", withExtension: "ini")!
|
||||
}
|
||||
|
||||
@Test func test_can_load_extension() throws {
|
||||
let extensions = PhpExtension.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
#expect(!extensions.isEmpty)
|
||||
}
|
||||
|
||||
@Test func test_extension_name_is_correct() throws {
|
||||
let extensions = PhpExtension.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
let extensionNames = extensions.map { (ext) -> String in
|
||||
return ext.name
|
||||
}
|
||||
|
||||
// These 6 should be found
|
||||
#expect(extensionNames.contains("xdebug"))
|
||||
#expect(extensionNames.contains("imagick"))
|
||||
#expect(extensionNames.contains("sodium-next"))
|
||||
#expect(extensionNames.contains("opcache"))
|
||||
#expect(extensionNames.contains("yaml"))
|
||||
#expect(extensionNames.contains("custom"))
|
||||
|
||||
#expect(extensionNames.contains("fake") == false)
|
||||
#expect(extensionNames.contains("nice") == false)
|
||||
}
|
||||
|
||||
@Test func test_extension_status_is_correct() throws {
|
||||
let extensions = PhpExtension.from(filePath: Self.phpIniFileUrl.path)
|
||||
|
||||
// xdebug should be enabled
|
||||
#expect(extensions[0].enabled == true)
|
||||
|
||||
// imagick should be disabled
|
||||
#expect(extensions[1].enabled == false)
|
||||
}
|
||||
|
||||
@Test func test_toggle_works_as_expected() async throws {
|
||||
let destination = Utility.copyToTemporaryFile(resourceName: "php", fileExtension: "ini")!
|
||||
let extensions = PhpExtension.from(filePath: destination.path)
|
||||
#expect(extensions.count == 6)
|
||||
|
||||
// Try to disable xdebug (should be detected first)!
|
||||
let xdebug = extensions.first!
|
||||
#expect(xdebug.name == "xdebug")
|
||||
#expect(xdebug.enabled == true)
|
||||
await xdebug.toggle()
|
||||
#expect(xdebug.enabled == false)
|
||||
|
||||
// Check if the file contains the appropriate data
|
||||
let file = try! String(contentsOf: destination, encoding: .utf8)
|
||||
#expect(file.contains("; zend_extension=\"xdebug.so\""))
|
||||
|
||||
// Make sure if we load the data again, it's disabled
|
||||
#expect(PhpExtension.from(filePath: destination.path).first!.enabled == false)
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
@Suite("Parsers")
|
||||
struct ValetConfigurationTest {
|
||||
static var jsonConfigFileUrl: URL {
|
||||
return TestBundle.url(
|
||||
@@ -18,8 +17,7 @@ struct ValetConfigurationTest {
|
||||
)!
|
||||
}
|
||||
|
||||
@Test("Can load config file")
|
||||
func can_load_config_file() throws {
|
||||
@Test func can_load_config_file() throws {
|
||||
let json = try? String(
|
||||
contentsOf: Self.jsonConfigFileUrl,
|
||||
encoding: .utf8
|
||||
@@ -37,5 +35,4 @@ struct ValetConfigurationTest {
|
||||
#expect(config.defaultSite == "/Users/username/default-site")
|
||||
#expect(config.loopback == "127.0.0.1")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
45
tests/unit/_ST/Parsers/ValetRcTest.swift
Normal file
45
tests/unit/_ST/Parsers/ValetRcTest.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// ValetRcTest.swift
|
||||
// Unit Tests
|
||||
//
|
||||
// Created by Nico Verbruggen on 20/01/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Testing
|
||||
import Foundation
|
||||
|
||||
struct ValetRcTest {
|
||||
// MARK: - Test Files
|
||||
static var validPath: URL {
|
||||
return TestBundle.url(forResource: "valetrc", withExtension: "valid")!
|
||||
}
|
||||
|
||||
static var brokenPath: URL {
|
||||
return TestBundle.url(forResource: "valetrc", withExtension: "broken")!
|
||||
}
|
||||
|
||||
// MARK: - Tests
|
||||
@Test func test_can_extract_fields_from_valet_rc_file() throws {
|
||||
let fakeFile = RCFile.fromPath("/Users/fake/file.rc")
|
||||
#expect(nil == fakeFile)
|
||||
|
||||
// Can parse the file
|
||||
let validFile = RCFile.fromPath(ValetRcTest.validPath.path)
|
||||
#expect(nil != validFile)
|
||||
|
||||
let fields = validFile!.fields
|
||||
|
||||
// Correctly parses and trims (and omits double quotes) per line
|
||||
#expect(fields["PHP"] == "php@8.2")
|
||||
#expect(fields["OTHER"] == "thing")
|
||||
#expect(fields["PHPMON_WATCH"] == "true")
|
||||
#expect(fields["SYNTAX"] == "variable")
|
||||
|
||||
// Ignores entries prefixed with #
|
||||
#expect(!fields.keys.contains("#PHP"))
|
||||
|
||||
// Ignores invalid lines
|
||||
#expect(!fields.keys.contains("OOF"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user