-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
kopiev.ivan
committed
Oct 17, 2024
1 parent
4c426cb
commit e88c575
Showing
12 changed files
with
373 additions
and
58 deletions.
There are no files selected for viewing
8 changes: 0 additions & 8 deletions
8
.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,30 @@ | ||
// swift-tools-version: 5.10 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "DeeplinkRouter", | ||
platforms: [.iOS(.v13)], | ||
products: [ | ||
// Products define the executables and libraries a package produces, making them visible to other packages. | ||
.library( | ||
name: "DeeplinkRouter", | ||
targets: ["DeeplinkRouter"]), | ||
], | ||
targets: [ | ||
// Targets are the basic building blocks of a package, defining a module or a test suite. | ||
// Targets can depend on other targets in this package and products from dependencies. | ||
.target( | ||
name: "DeeplinkRouter"), | ||
name: "DeeplinkRouter", | ||
dependencies: [], | ||
path: "Sources", | ||
exclude: [], | ||
resources: [], | ||
swiftSettings: [], | ||
linkerSettings: [ | ||
.linkedFramework("UIKit") | ||
] | ||
), | ||
.testTarget( | ||
name: "DeeplinkRouterTests", | ||
dependencies: ["DeeplinkRouter"]), | ||
dependencies: ["DeeplinkRouter"], | ||
path: "Tests" | ||
), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,69 @@ | ||
// | ||
// File.swift | ||
// | ||
// URLDecoder.swift | ||
// | ||
// | ||
// Created by Иван Копиев on 17.10.2024. | ||
// | ||
|
||
import Foundation | ||
|
||
// Класс для универсального парсинга URL в Codable объект | ||
final class URLDecoder: URLDecoderProtocol { | ||
|
||
// Универсальный метод для парсинга объекта Codable из URL query-параметров | ||
func decode<T: URLCodable>(type: T.Type, from url: URL, decoder: JSONDecoder) throws -> T { | ||
guard let queryParams = url.queryParameters else { | ||
print("No query parameters found in URL") | ||
throw URLError(.unsupportedURL) | ||
} | ||
// Преобразуем параметры в соответствующие типы на основе структуры Codable | ||
let convertedParams = convertParameters(queryParams, for: type) | ||
// Превращаем query-параметры в Data, подходящие для JSONDecoder | ||
let jsonData = try JSONSerialization.data(withJSONObject: convertedParams, options: []) | ||
let object = try decoder.decode(T.self, from: jsonData) | ||
return object | ||
} | ||
|
||
// Преобразование query-параметров в соответствующие типы на основе структуры | ||
private func convertParameters<T: URLCodable>( | ||
_ parameters: [String: String], | ||
for type: T.Type | ||
) -> [String: Any] { | ||
var convertedParams: [String: Any] = [:] | ||
|
||
// Используем Mirror для рефлексии структуры | ||
let mirror = Mirror(reflecting: type.template) | ||
|
||
for (key, value) in parameters { | ||
if let child = mirror.children.first(where: { $0.label == key }) { | ||
// Преобразуем строку в нужный тип на основе метаданных | ||
if child.value is Int, let intValue = Int(value) { | ||
convertedParams[key] = intValue | ||
} else if child.value is Double, let doubleValue = Double(value) { | ||
convertedParams[key] = doubleValue | ||
} else if child.value is Bool, let boolValue = Bool(value) { | ||
convertedParams[key] = boolValue | ||
} else { | ||
// Если это строка или неизвестный тип, оставляем как строку | ||
convertedParams[key] = value | ||
} | ||
} | ||
} | ||
return convertedParams | ||
} | ||
} | ||
|
||
// Расширение URL для парсинга query-параметров | ||
extension URL { | ||
// Извлекаем словарь query-параметров | ||
var queryParameters: [String: String]? { | ||
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false), | ||
let queryItems = components.queryItems else { return nil } | ||
|
||
var params: [String: String] = [:] | ||
for item in queryItems { | ||
params[item.name] = item.value | ||
} | ||
return params | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,91 @@ | ||
// | ||
// File.swift | ||
// | ||
// BaseNavigatorTests.swift | ||
// | ||
// | ||
// Created by Иван Копиев on 17.10.2024. | ||
// | ||
|
||
import Foundation | ||
import XCTest | ||
@testable import DeeplinkRouter | ||
|
||
final class BaseNavigatorTests: XCTestCase { | ||
|
||
var navigator: BaseNavigator! | ||
var window: UIWindow! | ||
|
||
override func setUp() { | ||
super.setUp() | ||
window = UIWindow() | ||
navigator = BaseNavigator(window: window) | ||
} | ||
|
||
func testWindowReturnsKeyWindow() { | ||
// Given | ||
window.makeKeyAndVisible() | ||
|
||
// When | ||
let returnedWindow = navigator.window | ||
|
||
// Then | ||
XCTAssertEqual(returnedWindow, window) | ||
} | ||
|
||
func testTopVcReturnsCorrectViewController() { | ||
// Given | ||
let rootViewController = UIViewController() | ||
window.rootViewController = rootViewController | ||
window.makeKeyAndVisible() | ||
|
||
// When | ||
let topVc = navigator.topVc | ||
|
||
// Then | ||
XCTAssertEqual(topVc, rootViewController) | ||
} | ||
|
||
func testTopNavControllerReturnsCorrectNavigationController() { | ||
// Given | ||
let window = UIWindow() | ||
navigator = BaseNavigator(window: window) | ||
let navController = UINavigationController() | ||
window.rootViewController = navController | ||
window.makeKeyAndVisible() | ||
|
||
// When | ||
let topNavController = navigator.topNavController | ||
|
||
// Then | ||
XCTAssertEqual(topNavController, navController) | ||
} | ||
|
||
func testTabbarReturnsCorrectTabBarController() { | ||
// Given | ||
let tabBarController = UITabBarController() | ||
window.rootViewController = tabBarController | ||
window.makeKeyAndVisible() | ||
|
||
// When | ||
let tabbar = navigator.tabbar | ||
|
||
// Then | ||
XCTAssertEqual(tabbar, tabBarController) | ||
} | ||
|
||
@MainActor | ||
func testSetLoadingShowsAndHidesLoader() { | ||
// Given | ||
window.makeKeyAndVisible() | ||
|
||
// When | ||
navigator.setLoading(true) | ||
|
||
// Then | ||
XCTAssertNotNil(window.viewWithTag(69)) | ||
|
||
// When | ||
navigator.setLoading(false) | ||
|
||
// Then | ||
XCTAssertNil(window.viewWithTag(69)) | ||
} | ||
} |
Oops, something went wrong.