- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스) - Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포 - 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
172 lines
5.3 KiB
Swift
172 lines
5.3 KiB
Swift
// Copyright 2021-present 650 Industries. All rights reserved.
|
|
|
|
import ExpoModulesTestCore
|
|
|
|
@testable import ExpoModulesCore
|
|
|
|
final class ExceptionsSpec: ExpoSpec {
|
|
override class func spec() {
|
|
let appContext = AppContext.create()
|
|
|
|
context("native") {
|
|
it("has name") {
|
|
let error = TestException()
|
|
expect(error.name) == "TestException"
|
|
}
|
|
|
|
it("has code") {
|
|
let error = TestException()
|
|
expect(error.code) == "ERR_TEST"
|
|
}
|
|
|
|
it("has reason") {
|
|
let error = TestException()
|
|
expect(error.reason) == "This is the test exception"
|
|
}
|
|
|
|
it("can be chained once") {
|
|
func throwable() throws {
|
|
do {
|
|
throw TestExceptionCause()
|
|
} catch {
|
|
throw TestException().causedBy(error)
|
|
}
|
|
}
|
|
expect { try throwable() }.to(throwError { error in
|
|
testChainedExceptionTypes(error: error, types: [TestException.self, TestExceptionCause.self])
|
|
})
|
|
}
|
|
|
|
it("can be chained twice") {
|
|
func throwable() throws {
|
|
do {
|
|
do {
|
|
throw TestExceptionCause()
|
|
} catch {
|
|
throw TestExceptionCause().causedBy(error)
|
|
}
|
|
} catch {
|
|
throw TestException().causedBy(error)
|
|
}
|
|
}
|
|
expect { try throwable() }.to(throwError { error in
|
|
testChainedExceptionTypes(error: error, types: [TestException.self, TestExceptionCause.self, TestExceptionCause.self])
|
|
})
|
|
}
|
|
|
|
it("includes cause description") {
|
|
func throwable() throws {
|
|
do {
|
|
throw TestExceptionCause()
|
|
} catch {
|
|
throw TestException().causedBy(error)
|
|
}
|
|
}
|
|
expect { try throwable() }.to(throwError { error in
|
|
if let error = error as? TestException, let cause = error.cause as? TestExceptionCause {
|
|
expect(error.description).to(contain(cause.description))
|
|
} else {
|
|
fail("Error and its cause are not of expected types.")
|
|
}
|
|
})
|
|
}
|
|
|
|
it("has root cause") {
|
|
let a = TestException()
|
|
let b = TestException().causedBy(a)
|
|
let c = TestException().causedBy(b)
|
|
|
|
expect(c.rootCause as! TestException) === a
|
|
}
|
|
}
|
|
|
|
context("JavaScript") {
|
|
let runtime = try! appContext.runtime
|
|
|
|
beforeSuite {
|
|
appContext.moduleRegistry.register(holder: mockModuleHolder(appContext) {
|
|
Name("TestModule")
|
|
|
|
Function("codedException") {
|
|
throw TestCodedException()
|
|
}
|
|
|
|
AsyncFunction("codedExceptionThrowAsync") { () in
|
|
throw TestCodedException()
|
|
}
|
|
|
|
AsyncFunction("codedExceptionRejectAsync") { (promise: Promise) in
|
|
promise.reject(TestCodedException())
|
|
}
|
|
|
|
AsyncFunction("codedExceptionConcurrentAsync") { () async throws in
|
|
throw TestCodedException()
|
|
}
|
|
})
|
|
}
|
|
|
|
it("sync function throw") {
|
|
let error = try runtime.eval("try { expo.modules.TestModule.codedException() } catch (error) { error }").asObject()
|
|
expect(error.getProperty("message").getString()).to(contain("FunctionCallException: Calling the 'codedException' function has failed"))
|
|
expect(error.getProperty("code").getString()).to(equal("E_TEST_CODE"))
|
|
}
|
|
|
|
// TODO: Find a way to evaluate async code
|
|
// it("async function throw") {
|
|
// let error = try runtime.eval("try { await expo.modules.TestModule.codedExceptionThrowAsync() } catch (error) { error }").asObject()
|
|
// expect(error.getProperty("code").getString()).to(equal("E_TEST_CODE"))
|
|
// }
|
|
|
|
// it("async function reject") {
|
|
// let error = try runtime.eval("try { await expo.modules.TestModule.codedExceptionRejectAsync() } catch (error) { error }").asObject()
|
|
// expect(error.getProperty("code").getString()).to(equal("E_TEST_CODE"))
|
|
// }
|
|
|
|
// it("async/concurrent function throw") {
|
|
// let error = try runtime.eval("try { await expo.modules.TestModule.codedExceptionConcurrentAsync() } catch (error) { error }").asObject()
|
|
// expect(error.getProperty("code").getString()).to(equal("E_TEST_CODE"))
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
class TestException: Exception {
|
|
override var reason: String {
|
|
"This is the test exception"
|
|
}
|
|
}
|
|
|
|
class TestExceptionCause: Exception {
|
|
override var reason: String {
|
|
"This is the cause of the test exception"
|
|
}
|
|
}
|
|
|
|
class TestCodedException: Exception {
|
|
init() {
|
|
super.init(name: "TestException",
|
|
description: "This is a test Exception with a code",
|
|
code: "E_TEST_CODE")
|
|
}
|
|
}
|
|
|
|
/**
|
|
Tests whether the exception chain matches given types and their order.
|
|
*/
|
|
private func testChainedExceptionTypes(error: Error, types: [Error.Type]) {
|
|
var next: Error? = error
|
|
|
|
for errorType in types {
|
|
let expectedErrorTypeName = String(describing: errorType)
|
|
let currentErrorTypeName = String(describing: type(of: next!))
|
|
|
|
expect(currentErrorTypeName).to(equal(expectedErrorTypeName), description: "The cause is not of type \(expectedErrorTypeName)")
|
|
|
|
if let chainableException = next as? ChainableException {
|
|
next = chainableException.cause
|
|
} else {
|
|
next = nil
|
|
}
|
|
}
|
|
}
|