From 87ff3929b62a68b8f14b60ce3438d80430d2a699 Mon Sep 17 00:00:00 2001 From: Tae Won Ha Date: Sat, 23 Dec 2023 20:55:42 +0100 Subject: [PATCH] Fix RxNeovimApi example --- .../Tests/NvimViewTests/NimbleCommons.swift | 2 +- RxPack/Package.swift | 6 +- .../RxNeovimTests/RxNeovimApiExample.swift | 120 ++++++++++++++++++ .../RxNeovimTests/RxNeovimApiTests.swift | 100 --------------- .../RxMsgpackRpcNeovimExample.swift | 36 +++--- 5 files changed, 144 insertions(+), 120 deletions(-) create mode 100644 RxPack/Tests/RxNeovimTests/RxNeovimApiExample.swift delete mode 100644 RxPack/Tests/RxNeovimTests/RxNeovimApiTests.swift diff --git a/NvimView/Tests/NvimViewTests/NimbleCommons.swift b/NvimView/Tests/NvimViewTests/NimbleCommons.swift index 47693e95..477bfff0 100644 --- a/NvimView/Tests/NvimViewTests/NimbleCommons.swift +++ b/NvimView/Tests/NvimViewTests/NimbleCommons.swift @@ -8,7 +8,7 @@ import Nimble // I don't know why the font returned by Typesetter is not equal to the font // it should be equal to. This is a workaround. -func equalFont(_ expectedValue: NSFont?) -> Predicate { +func equalFont(_ expectedValue: NSFont?) -> Nimble.Predicate { Predicate { actualExpression in let msg = ExpectationMessage.expectedActualValueTo( "equal <\(String(describing: expectedValue))>" diff --git a/RxPack/Package.swift b/RxPack/Package.swift index f9741a56..63d3ca1a 100644 --- a/RxPack/Package.swift +++ b/RxPack/Package.swift @@ -35,7 +35,11 @@ let package = Package( ), .testTarget( name: "RxNeovimTests", - dependencies: ["RxNeovim"] + dependencies: [ + "RxNeovim", + .product(name: "RxBlocking", package: "RxSwift"), + .product(name: "Nimble", package: "Nimble"), + ] ), ] ) diff --git a/RxPack/Tests/RxNeovimTests/RxNeovimApiExample.swift b/RxPack/Tests/RxNeovimTests/RxNeovimApiExample.swift new file mode 100644 index 00000000..498ebdd6 --- /dev/null +++ b/RxPack/Tests/RxNeovimTests/RxNeovimApiExample.swift @@ -0,0 +1,120 @@ +/// Tae Won Ha - http://taewon.de - @hataewon +/// See LICENSE + +import Nimble +import RxBlocking +import RxNeovim +import RxPack +import RxSwift +import XCTest + +private extension PrimitiveSequenceType { + func waitCompletion() throws { + _ = try self.primitiveSequence.toBlocking().first() + } +} + +private func delayingCompletable() -> Completable { + Single.just(0) + .delay(.milliseconds(10), scheduler: MainScheduler.instance) + .asCompletable() +} + +/// No real test, just a sample code to see that it works with Neovim +class RxNeovimApiExample: XCTestCase { + let api = RxNeovimApi() + let disposeBag = DisposeBag() + var proc: Process! + + override func setUp() { + super.setUp() + + self.api.msgpackRawStream.subscribe( + onNext: { msg in + switch msg { + case let .notification(method, params): + print("NOTIFICATION: \(method): array of \(params.count) elements") + case let .error(value, msg): + print("ERROR: \(msg) with \(value)") + case let .response(msgid, error, result): + print("RESPONSE: \(msgid), \(error), \(result)") + default: + fail("Unknown msg type from rpc") + } + }, + onError: { print("ERROR: \($0)") }, + onCompleted: { print("COMPLETED!") } + ) + .disposed(by: self.disposeBag) + + self.proc = neovimProcess() + let inPipe = self.proc.standardInput as! Pipe + let outPipe = self.proc.standardOutput as! Pipe + let errorPipe = self.proc.standardError as! Pipe + try! self.proc.run() + try! self.api.run(inPipe: inPipe, outPipe: outPipe, errorPipe: errorPipe).waitCompletion() + } + + override func tearDown() { + super.tearDown() + + try! self.api.command(command: "q!").waitCompletion() + self.proc.waitUntilExit() + } + + func testExample() throws { + try self.api.uiAttach(width: 80, height: 24, options: [:]).waitCompletion() + + let formatter = DateFormatter() + formatter.dateFormat = "mm:ss.SSS" + for i in 0...100 { + let date = Date() + let response = try self.api.commandOutput( + command: "echo '\(i) \(formatter.string(from: date))'" + ).toBlocking().first()! + Swift.print(response) + } + + let testFileUrl: URL = FileManager.default + .homeDirectoryForCurrentUser.appending(components: "test/big.swift") + guard FileManager.default.fileExists(atPath: testFileUrl.path) else { + try self.api.uiDetach().waitCompletion() + + return + } + + try self.api.command(command: "e \(testFileUrl.path)").waitCompletion() + + let lineCount = try self.api.bufLineCount(buffer: .init(0)).toBlocking().first()! + Swift.print("Line count of \(testFileUrl): \(lineCount)") + + let repeatCount = 200 + for _ in 0...repeatCount { + try self.api.input(keys: "").waitCompletion() + try delayingCompletable().waitCompletion() + } + for _ in 0...repeatCount { + try self.api.input(keys: "").waitCompletion() + try delayingCompletable().waitCompletion() + } + + Thread.sleep(forTimeInterval: 1) + + try self.api.uiDetach().waitCompletion() + } +} + +private func neovimProcess() -> Process { + let inPipe = Pipe() + let outPipe = Pipe() + let errorPipe = Pipe() + + let process = Process() + process.executableURL = URL(fileURLWithPath: "/opt/homebrew/bin/nvim") + process.standardInput = inPipe + process.standardError = errorPipe + process.standardOutput = outPipe + process.arguments = ["--embed"] + + return process +} diff --git a/RxPack/Tests/RxNeovimTests/RxNeovimApiTests.swift b/RxPack/Tests/RxNeovimTests/RxNeovimApiTests.swift deleted file mode 100644 index 59f62433..00000000 --- a/RxPack/Tests/RxNeovimTests/RxNeovimApiTests.swift +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Tae Won Ha - http://taewon.de - @hataewon - * See LICENSE - */ - -import MessagePack -import RxSwift -import XCTest - -@testable import RxPack - -class NvimMsgPackTests: XCTestCase { - var nvim = RxNeovimApi() - let disposeBag = DisposeBag() - - override func setUp() { - super.setUp() - - // $ NVIM_LISTEN_ADDRESS=/tmp/nvim.sock nvim $SOME_FILES - try? self.nvim.run(at: "/tmp/nvim.sock").wait() - } - - override func tearDown() { - super.tearDown() - try? self.nvim - .command(command: "q!") - .wait() - try? self.nvim.stop().wait() - } - - func testSth() { - let colorNames = [ - "Normal", // color and background-color - "Directory", // a - "StatusLine", // code background and foreground - "NonText", // hr and block quote border - "Question", // blockquote foreground - ] - - typealias HlResult = [String: RxNeovimApi.Value] - typealias ColorNameHlResultTuple = (colorName: String, hlResult: HlResult) - typealias ColorNameObservableTuple = (colorName: String, observable: Observable) - - Observable - .from(colorNames.map { colorName -> ColorNameObservableTuple in - ( - colorName: colorName, - observable: self.nvim - .getHlByName(name: colorName, rgb: true) - .asObservable() - ) - }) - .flatMap { tuple -> Observable<(String, HlResult)> in - Observable.zip(Observable.just(tuple.colorName), tuple.observable) - } - .subscribe(onNext: { (tuple: ColorNameHlResultTuple) in - print(tuple) - }) - .disposed(by: self.disposeBag) - -// Observable -// .concat(colorNames.map { colorName in -// self.nvim -// .getHlByName(name: colorName, rgb: true) -// .asObservable() -// }) -// .enumerated() -// .subscribe(onNext: { dict in print(dict) }) -// .disposed(by: self.disposeBag) - -// self.nvim -// .getHlByName(name: "Normal", rgb: true) -// .subscribe(onSuccess: { dict in -// guard let f = dict["foreground"]?.uint64Value, -// let b = dict["background"]?.uint64Value else { return } -// print(String(format: "%06X %06X", f, b)) -// }, onError: { err in print(err) }) -// .disposed(by: self.disposeBag) - - sleep(1) - } - - func testExample() { - let formatter = DateFormatter() - formatter.dateStyle = .short - formatter.timeStyle = .full - let now = Date() - let dispose = DisposeBag() - for i in 0...5 { - self.nvim - .command( - command: "echo '\(formatter.string(from: now)) \(i)'" - ) - .subscribe(onCompleted: { print("\(i) handled") }) - .disposed(by: dispose) - } - - sleep(1) - } -} diff --git a/RxPack/Tests/RxPackTests/RxMsgpackRpcNeovimExample.swift b/RxPack/Tests/RxPackTests/RxMsgpackRpcNeovimExample.swift index b3063a64..605f2506 100644 --- a/RxPack/Tests/RxPackTests/RxMsgpackRpcNeovimExample.swift +++ b/RxPack/Tests/RxPackTests/RxMsgpackRpcNeovimExample.swift @@ -7,7 +7,7 @@ import RxPack import RxSwift import XCTest -extension PrimitiveSequenceType { +private extension PrimitiveSequenceType { func waitCompletion() throws { _ = try self.primitiveSequence.toBlocking().first() } @@ -19,7 +19,7 @@ private func delayingCompletable() -> Completable { .asCompletable() } -/// No real test, just a sample code to see that it works with Neovim: Execute +/// No real test, just a sample code to see that it works with Neovim class RxMsgpackRpcNeovimExample: XCTestCase { let rpc = RxMsgpackRpc(queueQos: .default) let disposeBag = DisposeBag() @@ -46,7 +46,7 @@ class RxMsgpackRpcNeovimExample: XCTestCase { ) .disposed(by: self.disposeBag) - self.proc = self.neovimProcess() + self.proc = neovimProcess() let inPipe = self.proc.standardInput as! Pipe let outPipe = self.proc.standardOutput as! Pipe let errorPipe = self.proc.standardError as! Pipe @@ -130,19 +130,19 @@ class RxMsgpackRpcNeovimExample: XCTestCase { try self.rpc.request(method: "nvim_ui_detach", params: [], expectsReturnValue: false) .waitCompletion() } - - private func neovimProcess() -> Process { - let inPipe = Pipe() - let outPipe = Pipe() - let errorPipe = Pipe() - - let process = Process() - process.executableURL = URL(fileURLWithPath: "/opt/homebrew/bin/nvim") - process.standardInput = inPipe - process.standardError = errorPipe - process.standardOutput = outPipe - process.arguments = ["--embed"] - - return process - } +} + +private func neovimProcess() -> Process { + let inPipe = Pipe() + let outPipe = Pipe() + let errorPipe = Pipe() + + let process = Process() + process.executableURL = URL(fileURLWithPath: "/opt/homebrew/bin/nvim") + process.standardInput = inPipe + process.standardError = errorPipe + process.standardOutput = outPipe + process.arguments = ["--embed"] + + return process }