Skip to content

Commit 2b3a99e

Browse files
committed
🚨 Improve code coverage for expression evaluation
- Test invalid expressions - Test error descriptions
1 parent 19abab9 commit 2b3a99e

File tree

4 files changed

+109
-80
lines changed

4 files changed

+109
-80
lines changed

‎Sources/JSExpression.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ extension JSExpression {
9696

9797
if ReturnType.self == JSVoid.self {
9898
return .noReturnValue(defaultValue: JSVoid() as! ReturnType)
99-
} else {
100-
return .returnValueMandatory
10199
}
102100

101+
return .returnValueMandatory
102+
103103
}
104104

105105
///

‎Sources/JSTypes.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import CoreGraphics
1010
/// The `Void` return value.
1111
///
1212

13-
public final class JSVoid: Equatable, Decodable {
14-
public init() {}
15-
public init(from decoder: Decoder) {}
13+
public struct JSVoid: Equatable, Decodable {
1614
public static func == (lhs: JSVoid, rhs: JSVoid) -> Bool { return true }
1715
}

‎Tests/JavaScriptKit/Expressions/ExecutionTests.swift

Lines changed: 93 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,27 @@ extension ExecutionTests {
154154

155155
extension ExecutionTests {
156156

157+
/// Tests that an error is thrown when an argument cannot be encoded.
158+
func testHandleExpressionGenerationError() {
159+
160+
let value = NotSoEncodable(name: "Error")
161+
let method = JSFunction<JSVoid>("tester.refresh", arguments: [value])
162+
let resultExpectation = expectation(description: "Async execution callback is called")
163+
164+
testInWebView(expectations: [resultExpectation]) {
165+
webView in
166+
167+
method.evaluate(in: webView) {
168+
result in
169+
assert(Thread.isMainThread)
170+
resultExpectation.fulfill()
171+
self.assertInvalidExpressionError(result)
172+
}
173+
174+
}
175+
176+
}
177+
157178
/// Tests that an error is thrown when a value is returned and Void is expected.
158179
func testHandleUnexpectedReturnValue() {
159180

@@ -674,144 +695,115 @@ extension ExecutionTests {
674695

675696
extension ExecutionTests {
676697

677-
///
678-
/// S'assure que le résultat est un succès contenant la valeur donnée.
679-
///
680-
698+
/// Asserts that the result is a success containing the given value.
681699
func assertSuccess<R: Equatable, E>(_ result: Result<R, E>, expectedValue: R) {
682700

683701
switch result {
684702
case .success(let value):
685703
XCTAssertEqual(value, expectedValue)
686704

687705
case .failure(let error):
688-
XCTFail("Erreur innatendue : \(error)")
706+
XCTFail("Unexpected error : \(error)")
689707
}
690708

691709
}
692710

693-
///
694-
/// S'assure que le résultat est un succès contenant la valeur donnée.
695-
///
696-
697-
func assertSuccess<E>(_ result: Result<Void, E>, expectedValue: Void) {
698-
699-
switch result {
700-
case .success(let value):
701-
XCTAssertTrue(value == ())
702-
703-
case .failure(let error):
704-
XCTFail("Erreur innatendue : \(error)")
705-
}
706-
707-
}
708-
709-
///
710-
/// S'assure que le résultat est un succès contenant la valeur donnée.
711-
///
712-
711+
/// Asserts that the result is a success containing the given value.
713712
func assertSuccess<R: Equatable, E>(_ result: Result<[R], E>, expectedValue: Array<R>) {
714713

715714
switch result {
716715
case .success(let value):
717716
XCTAssertEqual(value, expectedValue)
718717

719718
case .failure(let error):
720-
XCTFail("Erreur innatendue : \(error)")
719+
XCTFail("Unexpected error : \(error)")
721720
}
722721

723722
}
724723

725-
///
726-
/// S'assure que le résultat est un échec de type causé par une mauvaise valeur donnée.
727-
///
728-
724+
/// Asserts that the result is an invalid type error.
729725
func assertInvalidTypeError<R, T: Equatable>(_ result: Result<R, JSErrorDomain>, expectedFailingValue: T) {
730726

731727
switch result {
732728
case .success(_):
733-
XCTFail("Une valeur a été retournée, alors qu'une erreur de type `invalidReturnType` était attendue.")
729+
XCTFail("A value was returned but an `invalidReturnType` error was expected.")
734730

735731
case .failure(let error):
736732

737733
switch error {
738734
case .invalidReturnType(let value):
739-
XCTAssertTrue((value as? T) == expectedFailingValue, "Une erreur de type a bien été retournée, mais la valeur posant problème ne correspond pas à celle attendue.")
740-
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "L'erreur ne provient pas du domaine attendu.")
735+
XCTAssertTrue((value as? T) == expectedFailingValue, "A type error was thrown, but the associated value does not match the expected one.")
736+
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "Incorrect error domain.")
737+
XCTAssertEqual(error.nsError.localizedDescription, error.errorDescription)
741738

742739
case .executionError(_):
743-
XCTFail("Une erreur de type `executionError` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
740+
XCTFail("An `executionError` error was thrown, expected`invalidReturnType` error.")
744741

745742
case .unexpectedResult:
746-
XCTFail("Une erreur de type `unexpectedResult` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
743+
XCTFail("An `unexpectedResult` error was thrown, expected `invalidReturnType` error.")
747744

748745
case .invalidExpression(_):
749-
XCTFail("Une erreur de type `invalidExpression` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
750-
746+
XCTFail("An `invalidExpression` error was thrown, expected `invalidReturnType` error.")
751747

752748
}
753749

754750
}
755751

756752
}
757753

758-
///
759-
/// S'assure que le résultat est un échec de type causé par une mauvaise valeur donnée.
760-
///
761-
754+
/// Asserts that the result is an invalid type error.
762755
func assertInvalidTypeError<R>(_ result: Result<[R], JSErrorDomain>, expectedFailingValue: [Any]) {
763756

764757
switch result {
765758
case .success(_):
766-
XCTFail("Une valeur a été retournée, alors qu'une erreur de type `invalidReturnType` était attendue.")
759+
XCTFail("A value was returned but an `invalidReturnType` error was expected.")
767760

768761
case .failure(let error):
769762

770763
switch error {
771764
case .invalidReturnType(let value):
772-
XCTAssertTrue((value as? NSArray)?.isEqual(to: expectedFailingValue) == true, "Une erreur de type a bien été retournée, mais la valeur posant problème ne correspond pas à celle attendue.")
773-
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "L'erreur ne provient pas du domaine attendu.")
765+
XCTAssertTrue((value as? NSArray)?.isEqual(to: expectedFailingValue) == true, "A type error was thrown, but the associated value does not match the expected one.")
766+
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "Incorrect error domain.")
767+
XCTAssertEqual(error.nsError.localizedDescription, error.errorDescription)
774768

775769
case .executionError(_):
776-
XCTFail("Une erreur de type `executionError` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
770+
XCTFail("An `executionError` error was thrown, expected`invalidReturnType` error.")
777771

778772
case .unexpectedResult:
779-
XCTFail("Une erreur de type `unexpectedResult` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
773+
XCTFail("An `unexpectedResult` error was thrown, expected `invalidReturnType` error.")
780774

781775
case .invalidExpression(_):
782-
XCTFail("Une erreur de type `unexpectedResult` a été retournée alors qu'une erreur de type `invalidExpression` était attendue.")
776+
XCTFail("An `unexpectedResult` error was thrown, expected `invalidExpression` error.")
783777

784778
}
785779

786780
}
787781

788782
}
789783

790-
///
791-
/// S'assure que le résultat est un échec de type causé par une mauvaise valeur donnée.
792-
///
793-
784+
/// Asserts that the result is an invalid type error.
794785
func assertInvalidTypeError<R>(_ result: Result<R, JSErrorDomain>, expectedFailingValue: [AnyHashable : Any]) {
795786

796787
switch result {
797788
case .success(_):
798-
XCTFail("Une valeur a été retournée, alors qu'une erreur de type `invalidReturnType` était attendue.")
789+
XCTFail("A value was returned but an `invalidReturnType` error was expected.")
799790

800791
case .failure(let error):
801792

802793
switch error {
803794
case .invalidReturnType(let value):
804-
XCTAssertTrue((value as? NSDictionary)?.isEqual(to: expectedFailingValue) == true, "Une erreur de type a bien été retournée, mais la valeur posant problème ne correspond pas à celle attendue.")
805-
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "L'erreur ne provient pas du domaine attendu.")
795+
XCTAssertTrue((value as? NSDictionary)?.isEqual(to: expectedFailingValue) == true, "A type error was thrown, but the associated value does not match the expected one.")
796+
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "Incorrect error domain.")
797+
XCTAssertEqual(error.nsError.localizedDescription, error.errorDescription)
806798

807799
case .executionError(_):
808-
XCTFail("Une erreur de type `executionError` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
800+
XCTFail("An `executionError` error was thrown, expected`invalidReturnType` error.")
809801

810802
case .unexpectedResult:
811-
XCTFail("Une erreur de type `unexpectedResult` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
803+
XCTFail("An `unexpectedResult` error was thrown, expected `invalidReturnType` error.")
812804

813805
case .invalidExpression(_):
814-
XCTFail("Une erreur de type `invalidExpression` a été retournée alors qu'une erreur de type `invalidReturnType` était attendue.")
806+
XCTFail("An `invalidExpression` error was thrown, expected `invalidReturnType` error.")
815807

816808

817809
}
@@ -821,61 +813,87 @@ extension ExecutionTests {
821813
}
822814

823815

824-
///
825-
/// S'assure que le résultat est un échec contenant le type donnée.
826-
///
827-
816+
/// Asserts that the result is an execution error.
828817
func assertExecutionError<R>(_ result: Result<R, JSErrorDomain>) {
829818

830819
switch result {
831820
case .success(_):
832-
XCTFail("Une valeur a été retournée, alors qu'une erreur de type `executionError` était attendue.")
821+
XCTFail("A value was returned but an `executionError` error was expected.")
833822

834823
case .failure(let error):
835824

836825
switch error {
837826
case .invalidReturnType(_):
838-
XCTFail("Une erreur de type `invalidReturnType` a été retournée alors qu'une erreur de type `executionError` était attendue.")
827+
XCTFail("An `invalidReturnType` error was thrown, expected `executionError` error.")
839828

840829
case .executionError(_):
841-
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "L'erreur ne provient pas du domaine attendu.")
830+
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "Incorrect error.")
831+
XCTAssertEqual(error.nsError.localizedDescription, error.errorDescription)
842832

843833
case .unexpectedResult:
844-
XCTFail("Une erreur de type `unexpectedResult` a été retournée alors qu'une erreur de type `executionError` était attendue.")
834+
XCTFail("An `unexpectedResult` error was thrown, expected `executionError` error.")
845835

846836
case .invalidExpression(_):
847-
XCTFail("Une erreur de type `invalidExpression` a été retournée alors qu'une erreur de type `executionError` était attendue.")
837+
XCTFail("An `invalidExpression` error was thrown, expected `executionError` error.")
848838

849839
}
850840

851841
}
852842

853843
}
854844

855-
///
856-
/// S'assure que le résultat est un échec contenant le type donnée.
857-
///
858-
845+
/// Asserts that the result is an unexpected result error.
859846
func assertUnexpectedResultError<R>(_ result: Result<R, JSErrorDomain>) {
860847

861848
switch result {
862849
case .success(_):
863-
XCTFail("Une valeur a été retournée, alors qu'une erreur de type `unexpectedResult` était attendue.")
850+
XCTFail("A value was returned but an `unexpectedResult` error was expected.")
864851

865852
case .failure(let error):
866853

867854
switch error {
868855
case .invalidReturnType(_):
869-
XCTFail("Une erreur de type `invalidReturnType` a été retournée alors qu'une erreur de type `unexpectedResult` était attendue.")
856+
XCTFail("An `invalidReturnType` error was thrown, expected`unexpectedResult` error.")
870857

871858
case .executionError(_):
872-
XCTFail("Une erreur de type `executionError` a été retournée alors qu'une erreur de type `unexpectedResult` était attendue.")
859+
XCTFail("An `executionError` error was thrown, expected`unexpectedResult` error.")
873860

874861
case .unexpectedResult:
875-
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "L'erreur ne provient pas du domaine attendu.")
862+
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier, "Incorrect error domain.")
863+
XCTAssertEqual(error.nsError.localizedDescription, error.errorDescription)
876864

877865
case .invalidExpression(_):
878-
XCTFail("Une erreur de type `invalidExpression` a été retournée alors qu'une erreur de type `unexpectedResult` était attendue.")
866+
XCTFail("An `invalidExpression` error was thrown, expected `unexpectedResult` error.")
867+
868+
}
869+
870+
}
871+
872+
}
873+
874+
/// Asserts that the result is an invalid expression error.
875+
func assertInvalidExpressionError<R>(_ result: Result<R, JSErrorDomain>) {
876+
877+
switch result {
878+
case .success(_):
879+
XCTFail("A value was returned but an `invalidExpression` error was expected.")
880+
881+
case .failure(let error):
882+
883+
switch error {
884+
case .invalidReturnType(_):
885+
XCTFail("An `invalidReturnType` error was thrown, expected`invalidExpression` error.")
886+
887+
case .executionError(_):
888+
XCTFail("An `executionError` error was thrown, expected `invalidExpression` error.")
889+
890+
case .unexpectedResult:
891+
XCTFail("An `unexpectedResult` error was thrown, expected `invalidExpression` error.")
892+
893+
case .invalidExpression(let underlyingError):
894+
XCTAssertEqual(error.nsError.domain, JSErrorDomain.identifier)
895+
XCTAssertEqual(underlyingError.domain, NSCocoaErrorDomain)
896+
XCTAssertEqual(error.nsError.localizedDescription, error.errorDescription)
879897

880898
}
881899

‎Tests/JavaScriptKit/Expressions/ExpressionModels.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,16 @@ struct MockTarget: Codable, Equatable {
3030
}
3131

3232
}
33+
34+
/// A structure that always fails encoding.
35+
struct NotSoEncodable: Encodable {
36+
37+
let name: String
38+
39+
func encode(to encoder: Encoder) throws {
40+
throw EncodingError.invalidValue(name,
41+
EncodingError.Context(codingPath: [],
42+
debugDescription: "NotSoEncodable structures cannot be encoded."))
43+
}
44+
45+
}

0 commit comments

Comments
 (0)