Add tests for `dev` and `bundle` commands (#196)
* carton dev and bundle default command tests * removed tests_output * removed .testfile * carton dev and bundle default command tests * removed localhost as localURL * attempt to fix folder name issue * removed Fixtures test folder * added Fixtures test folder * attempt to fix folder name issue * attempt to fix server connect issue * fixed dev testWithNoArguments with sleep delay * Debugging bundle command for github actions * Install wasmr prior to swift test * Debug clean up * Debug clean up * Update Tests/CartonCommandTests/CommandTestHelper.swift Co-authored-by: Max Desiatov <max@desiatov.com> Co-authored-by: thecb4 <cavelle@tehcb4.io> Co-authored-by: Max Desiatov <max@desiatov.com>
This commit is contained in:
parent
d7352b5a25
commit
22165481bf
|
@ -15,9 +15,9 @@ jobs:
|
|||
- name: Build on macOS 10.15 with Swift 5.2
|
||||
run: |
|
||||
sudo xcode-select --switch /Applications/Xcode_11.7.app/Contents/Developer
|
||||
brew bundle
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
brew bundle
|
||||
cd TestApp && ../.build/release/carton test
|
||||
../.build/release/carton test --environment defaultBrowser
|
||||
../.build/release/carton bundle
|
||||
|
@ -33,9 +33,9 @@ jobs:
|
|||
- name: Build on macOS 11.0 with Swift 5.2
|
||||
run: |
|
||||
sudo xcode-select --switch /Applications/Xcode_11.7.app/Contents/Developer
|
||||
brew bundle
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
brew bundle
|
||||
cd TestApp && ../.build/release/carton test
|
||||
../.build/release/carton test --environment defaultBrowser
|
||||
../.build/release/carton bundle
|
||||
|
@ -50,9 +50,9 @@ jobs:
|
|||
- name: Build on macOS 10.15 with Swift 5.3
|
||||
run: |
|
||||
sudo xcode-select --switch /Applications/Xcode_12.app/Contents/Developer
|
||||
brew bundle
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
brew bundle
|
||||
cd TestApp && ../.build/release/carton test
|
||||
../.build/release/carton test --environment defaultBrowser
|
||||
../.build/release/carton bundle
|
||||
|
@ -67,9 +67,9 @@ jobs:
|
|||
- name: Build on macOS 11.0 with Swift 5.3
|
||||
run: |
|
||||
sudo xcode-select --switch /Applications/Xcode_12.2.app/Contents/Developer
|
||||
brew bundle
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
brew bundle
|
||||
cd TestApp && ../.build/release/carton test
|
||||
../.build/release/carton test --environment defaultBrowser
|
||||
../.build/release/carton bundle
|
||||
|
@ -84,11 +84,11 @@ jobs:
|
|||
|
||||
- name: Build on Ubuntu 18.04 with Swift 5.3
|
||||
run: |
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
sudo ./install_ubuntu_deps.sh
|
||||
curl https://get.wasmer.io -sSfL | sh
|
||||
source /home/runner/.wasmer/wasmer.sh
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
cd TestApp && ../.build/release/carton test
|
||||
../.build/release/carton bundle
|
||||
env:
|
||||
|
@ -101,11 +101,11 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- name: Build on Ubuntu 20.04 with Swift 5.3
|
||||
run: |
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
sudo ./install_ubuntu_deps.sh
|
||||
curl https://get.wasmer.io -sSfL | sh
|
||||
source /home/runner/.wasmer/wasmer.sh
|
||||
swift test -c release --enable-test-discovery
|
||||
swift build -c release
|
||||
cd TestApp && ../.build/release/carton test
|
||||
../.build/release/carton bundle
|
||||
env:
|
||||
|
|
|
@ -115,6 +115,8 @@ let package = Package(
|
|||
name: "CartonCommandTests",
|
||||
dependencies: [
|
||||
"CartonCLI",
|
||||
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
||||
.product(name: "AsyncHTTPClient", package: "async-http-client"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -109,6 +109,8 @@ let package = Package(
|
|||
name: "CartonCommandTests",
|
||||
dependencies: [
|
||||
"CartonCLI",
|
||||
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
||||
.product(name: "AsyncHTTPClient", package: "async-http-client"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2020 Carton contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Created by Cavelle Benjamin on Dec/25/20.
|
||||
//
|
||||
|
||||
@testable import CartonCLI
|
||||
import TSCBasic
|
||||
import XCTest
|
||||
|
||||
extension BundleCommandTests: Testable {}
|
||||
|
||||
final class BundleCommandTests: XCTestCase {
|
||||
func testWithNoArguments() throws {
|
||||
// given I've created a directory
|
||||
let package = "Milk"
|
||||
let packageDirectory = testFixturesDirectory.appending(component: package)
|
||||
|
||||
let bundle = "Bundle"
|
||||
let bundleDirectory = packageDirectory.appending(component: bundle)
|
||||
|
||||
// it's ok if there is nothing to delete
|
||||
do { try bundleDirectory.delete() } catch {}
|
||||
|
||||
XCTAssertFalse(bundleDirectory.exists, "The Bundle directory should not exist")
|
||||
|
||||
AssertExecuteCommand(
|
||||
command: "carton bundle",
|
||||
cwd: packageDirectory.url
|
||||
)
|
||||
|
||||
// Confirm that the files are actually in the folder
|
||||
XCTAssertTrue(bundleDirectory.exists, "The Bundle directory should exist")
|
||||
XCTAssertTrue(bundleDirectory.ls().contains("index.html"), "Bundle does not have index.html")
|
||||
XCTAssertFalse(
|
||||
(bundleDirectory.ls().filter { $0.contains("wasm") }).isEmpty,
|
||||
".wasm file does not exist"
|
||||
)
|
||||
XCTAssertFalse(
|
||||
(bundleDirectory.ls().filter { $0.contains("js") }).isEmpty,
|
||||
".js does not exist"
|
||||
)
|
||||
|
||||
// finally, clean up
|
||||
try bundleDirectory.delete()
|
||||
try packageDirectory.appending(component: ".build").delete()
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//===----------------------------------------------------------*- swift -*-===//
|
||||
// ===----------------------------------------------------------*- swift -*-===//
|
||||
//
|
||||
// This source file is part of the Swift Argument Parser open source project
|
||||
//
|
||||
|
@ -7,11 +7,20 @@
|
|||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ===----------------------------------------------------------------------===//
|
||||
|
||||
import ArgumentParser
|
||||
import XCTest
|
||||
|
||||
public extension ExitCode {
|
||||
static var quit = ExitCode(SIGQUIT)
|
||||
}
|
||||
|
||||
public func stop(process id: Int32, exitCode: ExitCode = .success) {
|
||||
print("sending stop command")
|
||||
kill(id, exitCode.rawValue)
|
||||
}
|
||||
|
||||
// extensions to the ParsableArguments protocol to facilitate XCTestExpectation support
|
||||
public protocol TestableParsableArguments: ParsableArguments {
|
||||
var didValidateExpectation: XCTestExpectation { get }
|
||||
|
@ -177,19 +186,63 @@ public func AssertHelp<T: ParsableCommand, U: ParsableCommand>(
|
|||
)
|
||||
}
|
||||
|
||||
public class EmptyTest: XCTestCase {}
|
||||
|
||||
extension EmptyTest: Testable {}
|
||||
|
||||
public extension XCTest {
|
||||
static var debugURL: URL {
|
||||
let bundleURL = Bundle(for: EmptyTest.self).bundleURL
|
||||
var debugURL: URL {
|
||||
let bundleURL = Bundle(for: type(of: self)).bundleURL
|
||||
return bundleURL.lastPathComponent.hasSuffix("xctest")
|
||||
? bundleURL.deletingLastPathComponent()
|
||||
: bundleURL
|
||||
}
|
||||
|
||||
static func AssertExecuteCommand(
|
||||
func executeCommand(
|
||||
command: String,
|
||||
cwd: URL? = nil, // To allow for testing of file based output
|
||||
expected: String? = nil,
|
||||
exitCode: ExitCode = .success,
|
||||
debug: Bool = false,
|
||||
file: StaticString = #file, line: UInt = #line
|
||||
) -> Process? {
|
||||
let splitCommand = command.split(separator: " ")
|
||||
let arguments = splitCommand.dropFirst().map(String.init)
|
||||
|
||||
let commandName = String(splitCommand.first!)
|
||||
let commandURL = debugURL.appendingPathComponent(commandName)
|
||||
guard (try? commandURL.checkResourceIsReachable()) ?? false else {
|
||||
XCTFail("No executable at '\(commandURL.standardizedFileURL.path)'.",
|
||||
file: file, line: line)
|
||||
return nil
|
||||
}
|
||||
|
||||
let process = Process()
|
||||
if #available(macOS 10.13, *) {
|
||||
process.executableURL = commandURL
|
||||
} else {
|
||||
process.launchPath = commandURL.path
|
||||
}
|
||||
process.arguments = arguments
|
||||
|
||||
if let workingDirectory = cwd {
|
||||
process.currentDirectoryURL = workingDirectory
|
||||
}
|
||||
|
||||
let output = Pipe()
|
||||
process.standardOutput = output
|
||||
let error = Pipe()
|
||||
process.standardError = error
|
||||
|
||||
if #available(macOS 10.13, *) {
|
||||
guard (try? process.run()) != nil else {
|
||||
XCTFail("Couldn't run command process.", file: file, line: line)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
process.launch()
|
||||
}
|
||||
|
||||
return process
|
||||
}
|
||||
|
||||
func AssertExecuteCommand(
|
||||
command: String,
|
||||
cwd: URL? = nil, // To allow for testing of file based output
|
||||
expected: String? = nil,
|
||||
|
@ -233,74 +286,7 @@ public extension XCTest {
|
|||
} else {
|
||||
process.launch()
|
||||
}
|
||||
process.waitUntilExit()
|
||||
|
||||
let outputData = output.fileHandleForReading.readDataToEndOfFile()
|
||||
let outputActual = String(data: outputData, encoding: .utf8)!
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
if debug { print(outputActual) }
|
||||
|
||||
let errorData = error.fileHandleForReading.readDataToEndOfFile()
|
||||
let errorActual = String(data: errorData, encoding: .utf8)!
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
if let expected = expected {
|
||||
AssertEqualStringsIgnoringTrailingWhitespace(
|
||||
expected,
|
||||
errorActual + outputActual,
|
||||
file: file,
|
||||
line: line
|
||||
)
|
||||
}
|
||||
|
||||
XCTAssertEqual(process.terminationStatus, exitCode.rawValue, file: file, line: line)
|
||||
}
|
||||
|
||||
func AssertExecuteCommand(
|
||||
command: String,
|
||||
cwd: URL? = nil, // To allow for testing of file based output
|
||||
expected: String? = nil,
|
||||
exitCode: ExitCode = .success,
|
||||
debug: Bool = false,
|
||||
file: StaticString = #file, line: UInt = #line
|
||||
) {
|
||||
let splitCommand = command.split(separator: " ")
|
||||
let arguments = splitCommand.dropFirst().map(String.init)
|
||||
|
||||
let commandName = String(splitCommand.first!)
|
||||
let commandURL = XCTest.debugURL.appendingPathComponent(commandName)
|
||||
guard (try? commandURL.checkResourceIsReachable()) ?? false else {
|
||||
XCTFail("No executable at '\(commandURL.standardizedFileURL.path)'.",
|
||||
file: file, line: line)
|
||||
return
|
||||
}
|
||||
|
||||
let process = Process()
|
||||
if #available(macOS 10.13, *) {
|
||||
process.executableURL = commandURL
|
||||
} else {
|
||||
process.launchPath = commandURL.path
|
||||
}
|
||||
process.arguments = arguments
|
||||
|
||||
if let workingDirectory = cwd {
|
||||
process.currentDirectoryURL = workingDirectory
|
||||
}
|
||||
|
||||
let output = Pipe()
|
||||
process.standardOutput = output
|
||||
let error = Pipe()
|
||||
process.standardError = error
|
||||
|
||||
if #available(macOS 10.13, *) {
|
||||
guard (try? process.run()) != nil else {
|
||||
XCTFail("Couldn't run command process.", file: file, line: line)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
process.launch()
|
||||
}
|
||||
process.waitUntilExit()
|
||||
|
||||
let outputData = output.fileHandleForReading.readDataToEndOfFile()
|
||||
|
|
|
@ -15,10 +15,108 @@
|
|||
// Created by Cavelle Benjamin on Dec/20/20.
|
||||
//
|
||||
|
||||
import AsyncHTTPClient
|
||||
@testable import CartonCLI
|
||||
import XCTest
|
||||
|
||||
extension DevCommandTests: Testable {}
|
||||
|
||||
// Dev Command stub
|
||||
final class DevCommandTests: XCTestCase {}
|
||||
final class DevCommandTests: XCTestCase {
|
||||
var client: HTTPClient?
|
||||
|
||||
override func tearDown() {
|
||||
print("shutting down client")
|
||||
try? client?.syncShutdown()
|
||||
client = nil
|
||||
}
|
||||
|
||||
func testWithNoArguments() throws {
|
||||
let url = "http://127.0.0.1:8080"
|
||||
|
||||
// client time out for connecting and responding
|
||||
let timeOut: Int64 = 60
|
||||
|
||||
// client delay... let the server start up
|
||||
let delay: UInt32 = 30
|
||||
|
||||
// only try 5 times.
|
||||
let polls = 5
|
||||
|
||||
// the directory was built using `carton init --template tokamak`
|
||||
let package = "Milk"
|
||||
let packageDirectory = testFixturesDirectory.appending(component: package)
|
||||
XCTAssertTrue(
|
||||
packageDirectory.exists,
|
||||
"\(package) directory does not exist. Cannot execute tests."
|
||||
)
|
||||
|
||||
do { try packageDirectory.appending(component: ".build").delete() } catch {}
|
||||
|
||||
let expectedHtml =
|
||||
"""
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<script type="text/javascript" src="dev.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
guard let process = executeCommand(
|
||||
command: "carton dev --verbose",
|
||||
cwd: packageDirectory.url,
|
||||
debug: true
|
||||
) else {
|
||||
XCTFail("Could not create process")
|
||||
return
|
||||
}
|
||||
|
||||
let timeout = HTTPClient.Configuration.Timeout(
|
||||
connect: .seconds(timeOut),
|
||||
read: .seconds(timeOut)
|
||||
)
|
||||
|
||||
client = HTTPClient(eventLoopGroupProvider: .createNew,
|
||||
configuration: HTTPClient.Configuration(timeout: timeout))
|
||||
|
||||
var response: HTTPClient.Response?
|
||||
var count = 0
|
||||
|
||||
// give the server some time to start
|
||||
repeat {
|
||||
sleep(delay)
|
||||
response = try? client?.get(url: url).wait()
|
||||
count += 1
|
||||
} while count < polls && response == nil
|
||||
|
||||
// end the process regardless of success
|
||||
process.terminate()
|
||||
|
||||
if let response = response {
|
||||
XCTAssertTrue(response.status == .ok, "Response was not ok")
|
||||
|
||||
guard let data = (response.body.flatMap { $0.getData(at: 0, length: $0.readableBytes) })
|
||||
else {
|
||||
XCTFail("Could not map data")
|
||||
return
|
||||
}
|
||||
guard let actualHtml = String(data: data, encoding: .utf8) else {
|
||||
XCTFail("Could convert data to string")
|
||||
return
|
||||
}
|
||||
|
||||
// test may be brittle as the template may change over time.
|
||||
XCTAssertEqual(actualHtml, expectedHtml, "HTML output does not match")
|
||||
|
||||
} else {
|
||||
print("no response from server after \(count) tries or \(Int(count) * Int(delay)) seconds")
|
||||
XCTFail("Could not reach server")
|
||||
}
|
||||
|
||||
// clean up
|
||||
do { try packageDirectory.appending(component: ".build").delete() } catch {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===----------------------------------------------------------*- swift -*-===//
|
||||
// ===----------------------------------------------------------*- swift -*-===//
|
||||
//
|
||||
// This source file is part of the Swift Argument Parser open source project
|
||||
//
|
||||
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ===----------------------------------------------------------------------===//
|
||||
|
||||
extension Substring {
|
||||
func trimmed() -> Substring {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
xcuserdata/
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "JavaScriptKit",
|
||||
"repositoryURL": "https://github.com/swiftwasm/JavaScriptKit.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b7a02434c6e973c08c3fd5069105ef44dd82b891",
|
||||
"version": "0.9.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "OpenCombine",
|
||||
"repositoryURL": "https://github.com/TokamakUI/OpenCombine.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "bccff3e7c84bc559e1aa0aa9ca878400360d439d",
|
||||
"version": "0.12.0-alpha2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "OpenCombineJS",
|
||||
"repositoryURL": "https://github.com/swiftwasm/OpenCombineJS.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b346f955ed21ab44576e204a7554210c77f69b9b",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Runtime",
|
||||
"repositoryURL": "https://github.com/MaxDesiatov/Runtime.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "a617ead8a125a97e69d6100e4d27922006e82e0a",
|
||||
"version": "2.1.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Tokamak",
|
||||
"repositoryURL": "https://github.com/TokamakUI/Tokamak",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b4b0efca4de0ce9cff771649dfbcd13c5736e7f0",
|
||||
"version": "0.6.1"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// swift-tools-version:5.3
|
||||
import PackageDescription
|
||||
let package = Package(
|
||||
name: "Milk",
|
||||
platforms: [.macOS(.v11)],
|
||||
products: [
|
||||
.executable(name: "Milk", targets: ["Milk"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(name: "Tokamak", url: "https://github.com/TokamakUI/Tokamak", from: "0.6.1"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Milk",
|
||||
dependencies: [
|
||||
.product(name: "TokamakShim", package: "Tokamak"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "MilkTests",
|
||||
dependencies: ["Milk"]
|
||||
),
|
||||
]
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
# Milk
|
||||
|
||||
A description of this package.
|
|
@ -0,0 +1,19 @@
|
|||
import TokamakDOM
|
||||
|
||||
struct TokamakApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup("Tokamak App") {
|
||||
ContentView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView: View {
|
||||
var body: some View {
|
||||
Text("Hello, world!")
|
||||
}
|
||||
}
|
||||
|
||||
// @main attribute is not supported in SwiftPM apps.
|
||||
// See https://bugs.swift.org/browse/SR-12683 for more details.
|
||||
TokamakApp.main()
|
|
@ -0,0 +1,7 @@
|
|||
import XCTest
|
||||
|
||||
import MilkTests
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += MilkTests.allTests()
|
||||
XCTMain(tests)
|
|
@ -0,0 +1,47 @@
|
|||
import class Foundation.Bundle
|
||||
import XCTest
|
||||
|
||||
final class MilkTests: XCTestCase {
|
||||
func testExample() throws {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct
|
||||
// results.
|
||||
|
||||
// Some of the APIs that we use below are available in macOS 10.13 and above.
|
||||
guard #available(macOS 10.13, *) else {
|
||||
return
|
||||
}
|
||||
|
||||
let fooBinary = productsDirectory.appendingPathComponent("Milk")
|
||||
|
||||
let process = Process()
|
||||
process.executableURL = fooBinary
|
||||
|
||||
let pipe = Pipe()
|
||||
process.standardOutput = pipe
|
||||
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
|
||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||
let output = String(data: data, encoding: .utf8)
|
||||
|
||||
XCTAssertEqual(output, "Hello, world!\n")
|
||||
}
|
||||
|
||||
/// Returns path to the built products directory.
|
||||
var productsDirectory: URL {
|
||||
#if os(macOS)
|
||||
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
|
||||
return bundle.bundleURL.deletingLastPathComponent()
|
||||
}
|
||||
fatalError("couldn't find the products directory")
|
||||
#else
|
||||
return Bundle.main.bundleURL
|
||||
#endif
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testExample", testExample),
|
||||
]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import XCTest
|
||||
|
||||
#if !canImport(ObjectiveC)
|
||||
public func allTests() -> [XCTestCaseEntry] {
|
||||
[
|
||||
testCase(MilkTests.allTests),
|
||||
]
|
||||
}
|
||||
#endif
|
|
@ -4433,6 +4433,7 @@
|
|||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
|
|
Loading…
Reference in New Issue