Skip to content

Commit

Permalink
Implemented subscript based data access. Added tests. Closes #55 Rela…
Browse files Browse the repository at this point in the history
…tes to #43
  • Loading branch information
vexy committed Dec 20, 2023
1 parent d225a6d commit cbc6d8e
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
3 changes: 2 additions & 1 deletion Sources/Fridge/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ import Foundation
enum FridgeErrors: Error {
case networkingIssues(reason: String)
case storageIssues(reason: String)
case parsingIssues(reason: String)
case decodingIssues(reason: String)
case invalidIdentifier
}
20 changes: 19 additions & 1 deletion Sources/Fridge/Fridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,26 @@
import Foundation

/* PUBLIC * FRIDGE * INTERFACE */

/**
Fast, lightweight and _extremely_ flexible **fetch and store** mechanism
Source code: [Fridge @ github](https://github.com//vexy//Fridge)
- Author: **Vexy**
- Since: Fridge `0.1`
*/
public struct Fridge {
// ADD OTHER STUFF HERE
static subscript<D: Decodable> (identifier: String) -> D {
/// Tries to return frozen object given object odentifier
get throws {
// try to unfreeze the object using given identifier
guard let unfrozenObject: D = try? Fridge.unfreeze🪅🎉(identifier) else {
throw FridgeErrors.invalidIdentifier
}
return unfrozenObject
}
}
}

//MARK: - Network object fetching (iOS 15+ only)
Expand Down
10 changes: 5 additions & 5 deletions Sources/Fridge/Grabber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final internal class Grabber {
throw FridgeErrors.networkingIssues(reason: "Networking failed")
}
guard let decodedObject = try? JSONDecoder().decode(D.self, from: rawData) else {
throw FridgeErrors.parsingIssues(reason: "Unable to parse data.")
throw FridgeErrors.decodingIssues(reason: "Unable to parse data.")
}
// return decoded object
return decodedObject
Expand All @@ -48,7 +48,7 @@ final internal class Grabber {
throw FridgeErrors.networkingIssues(reason: "Networking failed")
}
guard let decodedObject = try? JSONDecoder().decode(D.self, from: rawData) else {
throw FridgeErrors.parsingIssues(reason: "Unable to parse data.")
throw FridgeErrors.decodingIssues(reason: "Unable to parse data.")
}
// return decoded object
return decodedObject
Expand Down Expand Up @@ -95,7 +95,7 @@ final internal class Grabber {
extension Grabber {
/// Constructs a JSON based `URLRequest` from given url `String`
private func constructURLRequest(from string: String) throws -> URLRequest {
guard let urlObject = URL(string: string) else { throw FridgeErrors.parsingIssues(reason: "Decoding failed.") }
guard let urlObject = URL(string: string) else { throw FridgeErrors.decodingIssues(reason: "Decoding failed.") }
var request = URLRequest(url: urlObject)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
Expand All @@ -106,15 +106,15 @@ extension Grabber {
/// Serialize given object and attach it to request body
private func serializeObject<E: Encodable>(_ objectToSerialize: E) throws -> Data {
guard let serializedObject = try? JSONEncoder().encode(objectToSerialize.self) else {
throw FridgeErrors.parsingIssues(reason: "Decoding failed.")
throw FridgeErrors.decodingIssues(reason: "Decoding failed.")
}
return serializedObject
}

/// Tries to decode given data into given `Decodable` object
private func deserializeData<D: Decodable>(_ rawData: Data) throws -> D {
guard let decodedObject = try? JSONDecoder().decode(D.self, from: rawData) else {
throw FridgeErrors.parsingIssues(reason: "Decoding failed")
throw FridgeErrors.decodingIssues(reason: "Decoding failed")
}
return decodedObject
}
Expand Down
File renamed without changes.
44 changes: 44 additions & 0 deletions Tests/FridgeTests/SubscriptTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// SubscriptTests.swift
//
//
// Created by Veljko Tekelerovic on 20.12.23.
//

import XCTest
import Foundation

@testable import Fridge

final class CustomSubscriptTests: XCTestCase {
private func freezeTestObject() throws {
let testObject = FridgeMockObject()
try Fridge.freeze🧊(testObject, id: STORAGE_IDENTIFIER)
}

func testInvalidIdentifierThrows_UsingSubscript() {
do {
let _ : FridgeMockObject = try Fridge["non_existant_id"]
XCTFail("Should'ev thrown an error")
} catch let err as FridgeErrors {
print("** Fridge error raised: ", err)
} catch let generalError {
print("General error is: ", generalError)
}
}

func testCanUnFreee_UsingSubscript() throws {
try freezeTestObject()

let frozenObject: FridgeMockObject = try Fridge[STORAGE_IDENTIFIER]

XCTAssert(frozenObject.string_field == "Some f🧊ncy string")
XCTAssert(frozenObject.int_field == Int.max)
XCTAssert(frozenObject.bool_field == false)
}

override class func tearDown() {
Fridge.drop🗑(STORAGE_IDENTIFIER)
print("\n** <Fridge.Tests> Test object removed from the file system **\n")
}
}

0 comments on commit cbc6d8e

Please sign in to comment.