Skip to content

Commit

Permalink
Improved tests, adds simple fail cases
Browse files Browse the repository at this point in the history
  • Loading branch information
André Vants committed Oct 6, 2021
1 parent 7a2956c commit 8ff6fda
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 94 deletions.
14 changes: 12 additions & 2 deletions .swiftpm/xcode/xcshareddata/xcschemes/WalletConnect.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,17 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "WalletConnect"
BuildableName = "WalletConnect"
BlueprintName = "WalletConnect"
ReferencedContainer = "container:">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
Expand All @@ -53,7 +63,7 @@
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
skipped = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "IntegrationTests"
Expand Down
4 changes: 4 additions & 0 deletions Example/ExampleApp/Proposer/ProposerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ extension ProposerViewController: UITableViewDataSource, UITableViewDelegate {

extension ProposerViewController: WalletConnectClientDelegate {

func didDelete(sessionTopic: String, reason: SessionType.Reason) {

}

func didReceive(sessionProposal: SessionType.Proposal) {
print("[PROPOSER] WC: Did receive session proposal")
}
Expand Down
10 changes: 7 additions & 3 deletions Example/ExampleApp/Responder/ResponderViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ extension ResponderViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let item = sessionItems[indexPath.row]
let deleteParams = SessionType.DeleteParams(topic: item.topic, reason: SessionType.Reason(code: 0, message: "disconnect"))
client.disconnect(params: deleteParams)
// let deleteParams = SessionType.DeleteParams(topic: item.topic, reason: SessionType.Reason(code: 0, message: "disconnect"))
client.disconnect(topic: item.topic, reason: SessionType.Reason(code: 0, message: "disconnect"))
sessionItems.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
Expand Down Expand Up @@ -118,7 +118,7 @@ extension ResponderViewController: SessionViewControllerDelegate {
print("[RESPONDER] Approving session...")
let proposal = currentProposal!
currentProposal = nil
client.approve(proposal: proposal)
client.approve(proposal: proposal, accounts: [])
}

func didRejectSession() {
Expand All @@ -131,6 +131,10 @@ extension ResponderViewController: SessionViewControllerDelegate {

extension ResponderViewController: WalletConnectClientDelegate {

func didDelete(sessionTopic: String, reason: SessionType.Reason) {

}

func didReceive(sessionProposal: SessionType.Proposal) {
print("[RESPONDER] WC: Did receive session proposal")
let appMetadata = sessionProposal.proposer.metadata
Expand Down
112 changes: 39 additions & 73 deletions Sources/WalletConnect/Utils/Types/AnyCodable.swift
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
import Foundation

public struct AnyCodable: Decodable, Encodable {
public struct AnyCodable {

public let value: Any

var customEncoder: ((Encoder) throws -> Void)?
private var genericEncoding: ((Encoder) throws -> Void)?

public init(_ value: Any) {
self.value = value
}

public init<C>(_ codable: C) where C: Codable {
self.value = codable
customEncoder = { encoder in
genericEncoding = { encoder in
try codable.encode(to: encoder)
}
}

public func get<T: Codable>(_ type: T.Type) -> T? {
if let data = try? JSONSerialization.data(withJSONObject: value, options: [.fragmentsAllowed]) {

if let decoded = try? JSONDecoder().decode(type, from: data) {
return decoded
}
}
return nil
public func get<T: Codable>(_ type: T.Type) throws -> T {
let valueData = try JSONSerialization.data(withJSONObject: value, options: [.fragmentsAllowed])
return try JSONDecoder().decode(type, from: valueData)
}
}

extension AnyCodable {
extension AnyCodable: Decodable, Encodable {

struct CodingKeys: CodingKey {

Expand All @@ -45,82 +40,23 @@ extension AnyCodable {
self.intValue = Int(stringValue)
}
}
}

extension AnyCodable {

public func encode(to encoder: Encoder) throws {
if let encod = customEncoder {
try encod(encoder)
return
}
// throw WalletConnectError.pairingProposalGenerationFailed

if let array = value as? [Any] {

var container = encoder.unkeyedContainer()

for value in array {
let decodable = AnyCodable(value)
try container.encode(decodable)
}
}

else if let dictionary = value as? [String: Any] {
var container = encoder.container(keyedBy: CodingKeys.self)
for (key, value) in dictionary {
let codingKey = CodingKeys(stringValue: key)!
let decodable = AnyCodable(value)
try container.encode(decodable, forKey: codingKey)
}
}

// else if let val = value as? Encodable {
//// var container = encoder.unkeyedContainer()
//// try container.encode(val)
// var container = encoder.container(keyedBy: CodingKeys.self)
//// try container.encode(val)
//// try container.encode(val, forKey: CodingKeys(stringValue: "key"))
// }

else {
var container = encoder.singleValueContainer()
if let intVal = value as? Int {
try container.encode(intVal)
} else if let doubleVal = value as? Double {
try container.encode(doubleVal)
} else if let boolVal = value as? Bool {
try container.encode(boolVal)
} else if let stringVal = value as? String {
try container.encode(stringVal)
} else {
throw EncodingError.invalidValue(value, EncodingError.Context.init(codingPath: [], debugDescription: "The value is not encodable"))
}
}
}
}

extension AnyCodable {

public init(from decoder: Decoder) throws {

if let container = try? decoder.container(keyedBy: CodingKeys.self) {

var result = [String: Any]()
try container.allKeys.forEach { (key) throws in
result[key.stringValue] = try container.decode(AnyCodable.self, forKey: key).value
}
value = result
}

else if var container = try? decoder.unkeyedContainer() {
var result = [Any]()
while !container.isAtEnd {
result.append(try container.decode(AnyCodable.self).value)
}
value = result
}

else if let container = try? decoder.singleValueContainer() {
if let intVal = try? container.decode(Int.self) {
value = intVal
Expand All @@ -137,10 +73,40 @@ extension AnyCodable {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not serialise"))
}
}

public func encode(to encoder: Encoder) throws {
if let encoding = genericEncoding {
try encoding(encoder)
} else if let array = value as? [Any] {
var container = encoder.unkeyedContainer()
for value in array {
let decodable = AnyCodable(value)
try container.encode(decodable)
}
} else if let dictionary = value as? [String: Any] {
var container = encoder.container(keyedBy: CodingKeys.self)
for (key, value) in dictionary {
let codingKey = CodingKeys(stringValue: key)!
let decodable = AnyCodable(value)
try container.encode(decodable, forKey: codingKey)
}
} else {
var container = encoder.singleValueContainer()
if let intVal = value as? Int {
try container.encode(intVal)
} else if let doubleVal = value as? Double {
try container.encode(doubleVal)
} else if let boolVal = value as? Bool {
try container.encode(boolVal)
} else if let stringVal = value as? String {
try container.encode(stringVal)
} else {
throw EncodingError.invalidValue(value, EncodingError.Context.init(codingPath: [], debugDescription: "The value is not encodable"))
}
}
}
}



extension AnyCodable: Equatable {
public static func == (lhs: AnyCodable, rhs: AnyCodable) -> Bool {
fatalError("Not implemented")
Expand Down
71 changes: 55 additions & 16 deletions Tests/WalletConnectTests/AnyCodableTests.swift
Original file line number Diff line number Diff line change
@@ -1,37 +1,59 @@
import XCTest
@testable import WalletConnect

struct CodableStub: Codable, Equatable {
fileprivate struct SampleStruct: Codable, Equatable {

let bool: Bool
let int: Int
let double: Double
let string: String
let object: Obje
let object: SubObject?

struct Obje: Codable, Equatable {
struct SubObject: Codable, Equatable {
let string: String
}

static func stub() -> CodableStub {
CodableStub(
static func stub() -> SampleStruct {
SampleStruct(
bool: Bool.random(),
int: Int.random(in: Int.min...Int.max),
double: Double.random(in: -1337.00...1337.00),
string: UUID().uuidString,
object: Obje(string: UUID().uuidString)
object: SubObject(string: UUID().uuidString)
)
}

static let sampleJSONData = """
{
"bool": true,
"int": 1337,
"double": 13.37,
"string": "verystringwow",
"object": {
"string": "0xdeadbeef"
}
}
""".data(using: .utf8)!

static let invalidJSONData = """
{
"bool": ****,
"int": 1337,
"double": 13.37,
"string": "verystringwow",
}
""".data(using: .utf8)!
}

class AnyCodableTests: XCTestCase {
final class AnyCodableTests: XCTestCase {

func testCodingBool() {
[true, false].forEach { bool in
do {
let anyCodable = AnyCodable(bool)
let encoded = try JSONEncoder().encode(anyCodable)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get(Bool.self)
let codingResult = try decoded.get(Bool.self)
XCTAssertEqual(bool, codingResult)
} catch {
XCTFail()
Expand All @@ -45,7 +67,7 @@ class AnyCodableTests: XCTestCase {
let anyCodable = AnyCodable(int)
let encoded = try JSONEncoder().encode(anyCodable)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get(Int.self)
let codingResult = try decoded.get(Int.self)
XCTAssertEqual(int, codingResult)
} catch {
XCTFail()
Expand All @@ -58,7 +80,7 @@ class AnyCodableTests: XCTestCase {
let anyCodable = AnyCodable(double)
let encoded = try JSONEncoder().encode(anyCodable)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get(Double.self)
let codingResult = try decoded.get(Double.self)
XCTAssertEqual(double, codingResult)
} catch {
XCTFail()
Expand All @@ -71,7 +93,7 @@ class AnyCodableTests: XCTestCase {
let anyCodable = AnyCodable(string)
let encoded = try JSONEncoder().encode(anyCodable)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get(String.self)
let codingResult = try decoded.get(String.self)
XCTAssertEqual(string, codingResult)
} catch {
XCTFail()
Expand All @@ -84,7 +106,7 @@ class AnyCodableTests: XCTestCase {
let anyCodable = AnyCodable(array)
let encoded = try JSONEncoder().encode(anyCodable)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get([String].self)
let codingResult = try decoded.get([String].self)
XCTAssertEqual(array, codingResult)
} catch {
XCTFail()
Expand All @@ -93,11 +115,11 @@ class AnyCodableTests: XCTestCase {

func testCodingStruct() {
do {
let object = CodableStub.stub()
let object = SampleStruct.stub()
let value = AnyCodable(object)
let encoded = try JSONEncoder().encode(value)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get(CodableStub.self)
let codingResult = try decoded.get(SampleStruct.self)
XCTAssertEqual(object, codingResult)
} catch {
XCTFail()
Expand All @@ -106,14 +128,31 @@ class AnyCodableTests: XCTestCase {

func testCodingStructArray() {
do {
let objects = (1...10).map { _ in CodableStub.stub() }
let objects = (1...10).map { _ in SampleStruct.stub() }
let value = AnyCodable(objects)
let encoded = try JSONEncoder().encode(value)
let decoded = try JSONDecoder().decode(AnyCodable.self, from: encoded)
let codingResult = decoded.get([CodableStub].self)
let codingResult = try decoded.get([SampleStruct].self)
XCTAssertEqual(objects, codingResult)
} catch {
XCTFail()
}
}

func testDecoding() {
do {
let data = SampleStruct.sampleJSONData
let decoded = try JSONDecoder().decode(AnyCodable.self, from: data)
_ = try JSONEncoder().encode(decoded)
} catch {
XCTFail()
}
}

func testDecodeFail() {
let data = SampleStruct.invalidJSONData
XCTAssertThrowsError(try JSONDecoder().decode(AnyCodable.self, from: data)) { error in
XCTAssert(error is DecodingError)
}
}
}

0 comments on commit 8ff6fda

Please sign in to comment.