Skip to content

Commit

Permalink
Finish tests
Browse files Browse the repository at this point in the history
  • Loading branch information
za-creature committed Jan 24, 2025
1 parent e3e02cd commit ae19ac4
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 8 deletions.
6 changes: 3 additions & 3 deletions bindings/swift/Ouisync/Sources/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public var ouisyncLogHandler: ((LogLevel, String) -> Void)?
// init_log is not safe to call repeatedly, should only be called before the first server is
// started and provides awkward memory semantics to assist dart, though we may eventually end up
// using them here as well if ever we end up making logging async
private func directLogHandler(_ message: LogMessage) {
defer { release_log_message(message) }
ouisyncLogHandler?(message.level, String(cString: message.ptr))
private func directLogHandler(_ level: LogLevel, _ ptr: UnsafePointer<UInt8>?, _ len: UInt, _ cap: UInt) {
defer { release_log_message(ptr, len, cap) }
if let ptr { ouisyncLogHandler?(level, String(cString: ptr)) }
}
@MainActor private var loggingConfigured = false
@MainActor private func setupLogging() async throws {
Expand Down
61 changes: 61 additions & 0 deletions bindings/swift/Ouisync/Tests/MoveEntryTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import XCTest
import Ouisync


final class MoveEntryTests: XCTestCase {
var server: Server!, client: Client!, temp: String!
override func setUp() async throws { (server, client, temp) = try await startServer(self) }
override func tearDown() async throws { try await cleanupServer(server, temp) }

func testMoveEmptyFolder() async throws {
// prep
let repo = try await client.createRepository(at: "foo")
try await repo.createDirectory(at: "/folder1");
try await repo.createDirectory(at: "/folder1/folder2");

// initial assertions
var list = try await repo.listDirectory(at: "/")
XCTAssertEqual(list.count, 1) // root only contains one entry (folder1)
list = try await repo.listDirectory(at: "/folder1/folder2")
XCTAssertEqual(list.count, 0) // folder2 is empty

try await repo.moveEntry(from: "/folder1/folder2", to: "/folder2") // move folder2 to root

// final assertions
list = try await repo.listDirectory(at: "/folder1")
XCTAssertEqual(list.count, 0) // folder1 is now empty
list = try await repo.listDirectory(at: "/")
XCTAssertEqual(list.count, 2) // root now contains folder1 AND folder2
}

func testMoveNonEmptyFolder() async throws {
// prep
let repo = try await client.createRepository(at: "bar")
try await repo.createDirectory(at: "/folder1");
try await repo.createDirectory(at: "/folder1/folder2");
var file: File! = try await repo.createFile(at: "/folder1/folder2/file1.txt")
let send = "hello world".data(using: .utf8)!
try await file.write(send, toOffset: 0)
try await file.flush()
file = nil

// initial assertions
var list = try await repo.listDirectory(at: "/")
XCTAssertEqual(list.count, 1) // root only contains one entry (folder1)
list = try await repo.listDirectory(at: "/folder1/folder2")
XCTAssertEqual(list.count, 1) // folder2 only contains one entry (file1)

try await repo.moveEntry(from: "/folder1/folder2", to: "/folder2") // move folder2 to root

// final assertions
list = try await repo.listDirectory(at: "/folder1")
XCTAssertEqual(list.count, 0) // folder1 is now empty
list = try await repo.listDirectory(at: "/")
XCTAssertEqual(list.count, 2) // root now contains folder1 AND folder2
list = try await repo.listDirectory(at: "/folder2")
XCTAssertEqual(list.count, 1) // folder2 still contains one entry (file1)
file = try await repo.openFile(at: "/folder2/file1.txt")
let recv = try await file.read(file.length, fromOffset: 0)
XCTAssertEqual(send, recv) // file1 contains the same data it used to
}
}
2 changes: 1 addition & 1 deletion bindings/swift/Ouisync/Tests/_Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import XCTest


func startServer(_ test: XCTestCase, suffix: String = "") async throws -> (Server, Client, String) {
//ouisyncLogHandler = { level, message in print(message) }
if envFlag("ENABLE_LOGGING") { ouisyncLogHandler = { level, message in print(message) } }
let path = test.name.replacingOccurrences(of: "-[", with: "")
.replacingOccurrences(of: "]", with: "")
.replacingOccurrences(of: " ", with: "_") + suffix
Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Ouisync/cov.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env zsh
INCLUDE_SLOW=1 swift test --enable-code-coverage
ENABLE_LOGGING=1 INCLUDE_SLOW=1 swift test --enable-code-coverage || echo "One or more tests failed" && exit 1
if [ "$1" = "report" ]; then
xcrun llvm-cov report .build/debug/OuisyncPackageTests.xctest/Contents/MacOS/OuisyncPackageTests -instr-profile .build/debug/codecov/default.profdata --sources Sources/
else
Expand Down
7 changes: 4 additions & 3 deletions service/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ fn init(
Ok((runtime, service, span))
}

pub type LogCallback = extern "C" fn(LogLevel, *const c_uchar, c_ulong, c_ulong);
// hoist Option here as a workaround for https://github.com/mozilla/cbindgen/issues/326
pub type OptionLogCallback = Option<extern "C" fn(LogLevel, *const c_uchar, c_ulong, c_ulong) -> ()>;

/// Initialize logging. Should be called before `service_start`.
///
Expand All @@ -180,7 +181,7 @@ pub type LogCallback = extern "C" fn(LogLevel, *const c_uchar, c_ulong, c_ulong)
///
/// `file` must be either null or it must be safe to pass to [std::ffi::CStr::from_ptr].
#[no_mangle]
pub unsafe extern "C" fn init_log(file: *const c_char, callback: Option<LogCallback>) -> ErrorCode {
pub unsafe extern "C" fn init_log(file: *const c_char, callback: OptionLogCallback) -> ErrorCode {
try_init_log(file, callback).to_error_code()
}

Expand All @@ -206,7 +207,7 @@ struct LoggerWrapper {

static LOGGER: OnceLock<LoggerWrapper> = OnceLock::new();

unsafe fn try_init_log(file: *const c_char, callback: Option<LogCallback>) -> Result<(), Error> {
unsafe fn try_init_log(file: *const c_char, callback: OptionLogCallback) -> Result<(), Error> {
let builder = Logger::builder();
let builder = if !file.is_null() {
builder.file(Path::new(CStr::from_ptr(file).to_str()?))
Expand Down

0 comments on commit ae19ac4

Please sign in to comment.