From 438d77ac0968f9e81b791d6e79b58bd1f3c384db Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:51:48 -0300 Subject: [PATCH 01/16] doc: system design (#1) --- README.md | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e9bf15b..655453b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,160 @@ # exchanges-app -iOS app to list exchanges list from CoinMaketCap Api +A simple iOS application that displays a list of cryptocurrency exchanges and their details using the CoinMarketCap API. + +## Functional requirements +- **User can:** + - view a list of cryptocurrency exchanges. + - view details of a specific exchange. + - view details of a specific exchange using deeplinks + - visit the exchange's website from the app + - view the app in light and dark mode + - view a loading indicator while data is being fetched + - view an error message if data fetching fails + - retry fetching data if an error occurs + +## Non-functional requirements +- **The app:** + - should have a clean and user-friendly UI. + - should be responsive and work on different screen sizes. + - should be performant and load data quickly. + - should consider scalability for future features and enhancements. + - should follow best practices for iOS development. + +## Data Entities Definitions +- **PreLoadedExchanges:** A list of exchanges with basic information (id, name) that is preloaded in the app for quick access. +- **Exchange:** Represents a cryptocurrency exchange with basic details such as id, name, spot volume in USD, date launched, and logo. +- **ExchangeDetail:** Represents detailed information about a specific exchange, including description, fees, weekly visits, and associated assets. +- **ExchangeURLs:** Contains various URLs related to the exchange, such as website, social media links, and fee information. +- **Assets:** Represents assets traded on the exchange, including id, name, symbol, and price in USD. +- **Status:** Represents the status of the API response, including timestamp, error code, error message, elapsed time, and credit count. + +## Entity Relationship Diagram + +```mermaid +erDiagram + PreLoadedExchange { + Int id + String name + } + + Exchange { + Int id + String name + Double spot_volume_usd + Date date_launched + String logo + } + + ExchangeDetail ||--|| ExchangeURLs : "contains" + ExchangeDetail ||--o{ Assets : "includes" + + ExchangeDetail { + Int id + String name + String description + String logo + Double spot_volume_usd + Double marker_fee + Double taker_fee + Date date_launched + Int weekly_visits + } + + ExchangeURLs { + String_array website + String_array twitter + String_array blog + String_array chats + String_array fee + } + + Assets { + Int id + String name + String symbol + Double price_usd + } + + Status { + Date timestamp + Int error_Code + String error_Message + Int elapsed + Int credit_Count + } +``` + +## API Endpoints + +The application integrates with CoinMarketCap API using the following service layer endpoints: + +### 1. List Exchanges (Mapping) +`GET /v1/exchange/map` +- **Purpose:** Retrieves a lightweight list of list of exchanges. +- **Usage:** Used during the Bootstrap/Pre-loading phase to map exchange names to IDs and populate selection components. +- **Key Response:** PreLoadedExchanges entity. + +### 2. Exchange Metadata +`GET /v1/exchange/info?id={ids}` + +- **Purpose:** Fetches comprehensive metadata for one or more exchanges. +- **Usage:** Powers the Exchange Detail view, providing logos, descriptions, and official website URLs. +- **Parameter:** Supports a comma-separated list of IDs (e.g., id=1,2,3). +- **Key Response:** ExchangeDetail entity. + +### 3. Exchange Assets (Holdings) +`GET /v1/exchange/assets?id={id}` + +- **Purpose**: Returns the asset holdings (Proof of Reserves) for a specific exchange. +- **Usage:** Displays the Token Composition within the exchange details, including wallet addresses and balances across different blockchains. +- **Key Response:** List of Assets entities. + +## Error Handling & Status Codes +The system maps API responses to specific application states. Below are the handled HTTP status codes: + +| Status Code | Label | Description | +| :--- | :--- | :--- | +| **401** | Unauthorized | API Key is missing or invalid. | +| **403** | Forbidden | The IP is blacklisted or the API Key lacks required permissions. | +| **429** | Too Many Requests | Rate limit exceeded. The system implements a back-off strategy. | +| **500** | Internal Server Error | CoinMarketCap server-side issue. | + +- **Key Response:** Status entity. + +## High-Level Design (MVVM-C) +The application architecture is based on the MVVM-C (Model-View-ViewModel + Coordinator) pattern. This approach ensures a clear separation of concerns, improves testability, and centralizes navigation logic. + +### Architectural Components +- **Coordinator:** The "brain" of navigation. It removes the responsibility of flow control from View Controllers, making them independent and reusable. It handles the instantiation of ViewControllers and ViewModels. +- **ViewModel:** Acts as a mediator between the Model and the View. It holds the business logic, formats data for display, and is completely unaware of the UI framework (UIKit/SwiftUI), which makes it ideal for Unit Testing. +- **View (ViewController):** Responsible only for layout and capturing user interactions. It binds to the ViewModel to receive updates. +- **Network / API:** Handles all network requests and responses, abstracting the details of API communication. + +Model: Represents the data structures and the business logic layer (Repositories and Services). + +```mermaid +graph LR + %% Estilos + classDef coordinator fill:#f9f,stroke:#333,stroke-width:2px; + classDef view fill:#bbf,stroke:#333,stroke-width:2px; + classDef viewModel fill:#dfd,stroke:#333,stroke-width:2px; + classDef data fill:#ffd,stroke:#333,stroke-width:2px; + classDef di fill:#fff4dd,stroke:#d4a017,stroke-width:2px,stroke-dasharray: 5 5; + + %% Componentes + CO[Coordinator]:::coordinator + VC[ViewController]:::view + VM[ViewModel]:::viewModel + API[Network / API]:::data + DI[Dependency Injection]:::di + + %% Fluxo de Injeção + DI -.->|Provides Dependencies| CO + + %% Fluxo Horizontal + CO -->|Instantiates| VC + CO -->|Injects| VM + VC <-->|Data Binding| VM + VM -->|Requests Data| API + API -.->|JSON Response| VM +``` \ No newline at end of file From 9036018c017054d3c17fb6caccd4991e43cc7aee Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Fri, 6 Feb 2026 14:11:33 -0300 Subject: [PATCH 02/16] feat: scripts and pr workflow (#15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: vitor-rc1 <“vitor_rc@outlook.com”> --- .github/workflows/pr_status.yml | 18 ++++++++++++++++++ Brewfile | 4 ++++ Gemfile | 3 +++ Makefile | 8 ++++++++ scripts/ci-setup.sh | 22 ++++++++++++++++++++++ scripts/generate-project.sh | 2 ++ scripts/local-setup.sh | 28 ++++++++++++++++++++++++++++ 7 files changed, 85 insertions(+) create mode 100644 .github/workflows/pr_status.yml create mode 100644 Brewfile create mode 100644 Gemfile create mode 100644 Makefile create mode 100644 scripts/ci-setup.sh create mode 100644 scripts/generate-project.sh create mode 100644 scripts/local-setup.sh diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml new file mode 100644 index 0000000..68660a3 --- /dev/null +++ b/.github/workflows/pr_status.yml @@ -0,0 +1,18 @@ +name: Pull request workflow + +on: + pull_request: + branches: [ "develop", "main" ] + +jobs: + test: + name: Setup project + runs-on: macos-26 + permissions: + pull-requests: write + issues: write + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - name: CI Setup + run: make ci-setup \ No newline at end of file diff --git a/Brewfile b/Brewfile new file mode 100644 index 0000000..47139da --- /dev/null +++ b/Brewfile @@ -0,0 +1,4 @@ +tap "tuist/tuist" + +brew "tuist" +brew "swiftlint" \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..37ef80d --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane", "~> 2.232.0" \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8a9ec23 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +generate-project: + @sh ./scripts/generate-project.sh + +local-setup: + @sh ./scripts/local-setup.sh + +ci-setup: + @sh ./scripts/ci-setup.sh \ No newline at end of file diff --git a/scripts/ci-setup.sh b/scripts/ci-setup.sh new file mode 100644 index 0000000..1e85015 --- /dev/null +++ b/scripts/ci-setup.sh @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +echo "CI setup Started" + +echo "Installing Brew dependencies..." +brew bundle install +echo "✅ Brew dependencies installed." + +echo "Installing Bundles..." +bundle install +echo "✅ Bundles installed." + +echo "Selecting Xcode..." +xcodes select 26.2.0 +echo "✅ Xcode selected." + +echo "Installing Project dependecies..." +tuist install +echo "✅ Project dependencies installed." + +echo "✅ CI setup completed." \ No newline at end of file diff --git a/scripts/generate-project.sh b/scripts/generate-project.sh new file mode 100644 index 0000000..4d62bd8 --- /dev/null +++ b/scripts/generate-project.sh @@ -0,0 +1,2 @@ +tuist install +tuist generate \ No newline at end of file diff --git a/scripts/local-setup.sh b/scripts/local-setup.sh new file mode 100644 index 0000000..ac891f8 --- /dev/null +++ b/scripts/local-setup.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +echo "✅ Local setup started." + +if command -v brew >/dev/null 2>&1; then + echo "✅ Homebrew found." +else + echo "⚠️ Homebrew not found. Please install manually following:" + echo "https://brew.sh/" + exit 1 +fi + +if command -v gem >/dev/null 2>&1; then + echo "✅ RubyGems found." +else + echo "⚠️ RubyGems not found. Please install manually." + exit 1 +fi + +echo "Installing Brew dependencies..." +brew bundle install +echo "✅ Brew dependencies installed." + +echo "Installing Bundles..." +bundle install +echo "✅ Bundles installed." + +echo "✅ Local setup completed." \ No newline at end of file From 5d61c523a915f003fd8bedc9ab0f06cdefd77cc9 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Fri, 6 Feb 2026 17:29:59 -0300 Subject: [PATCH 03/16] feat: tuist scaffold (#16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: vitor-rc1 <“vitor_rc@outlook.com”> --- .github/workflows/pr_status.yml | 6 +- .gitignore | 108 +++++++++-------- Projects/App/Info.plist | 38 ++++++ Projects/App/Project.swift | 55 +++++++++ .../AccentColor.colorset/Contents.json | 11 ++ .../AppIcon.appiconset/Contents.json | 35 ++++++ .../Resources/Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 ++++ Projects/App/Sources/AppDelegate.swift | 24 ++++ Projects/App/Sources/SceneDelegate.swift | 36 ++++++ Projects/App/Sources/ViewController.swift | 16 +++ Projects/App/Tests/ExchangesAppTests.swift | 17 +++ .../App/UITests/ExchangesAppUITests.swift | 41 +++++++ .../ExchangesAppUITestsLaunchTests.swift | 33 +++++ Tuist/Package.swift | 15 +++ .../Project+Template.swift | 113 ++++++++++++++++++ Workspace.swift | 11 ++ 17 files changed, 539 insertions(+), 51 deletions(-) create mode 100644 Projects/App/Info.plist create mode 100644 Projects/App/Project.swift create mode 100644 Projects/App/Resources/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Projects/App/Resources/Assets.xcassets/Contents.json create mode 100644 Projects/App/Resources/Base.lproj/LaunchScreen.storyboard create mode 100644 Projects/App/Sources/AppDelegate.swift create mode 100644 Projects/App/Sources/SceneDelegate.swift create mode 100644 Projects/App/Sources/ViewController.swift create mode 100644 Projects/App/Tests/ExchangesAppTests.swift create mode 100644 Projects/App/UITests/ExchangesAppUITests.swift create mode 100644 Projects/App/UITests/ExchangesAppUITestsLaunchTests.swift create mode 100644 Tuist/Package.swift create mode 100644 Tuist/ProjectDescriptionHelpers/Project+Template.swift create mode 100644 Workspace.swift diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index 68660a3..ff452f9 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -15,4 +15,8 @@ jobs: - name: Checkout uses: actions/checkout@v4.1.1 - name: CI Setup - run: make ci-setup \ No newline at end of file + run: make ci-setup + - name: Install dependencies + run: tuist install + - name: Generate project + run: tuist generate --no-open \ No newline at end of file diff --git a/.gitignore b/.gitignore index 52fe2f7..24b244f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,32 @@ +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Xcode ### # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore @@ -5,58 +34,37 @@ ## User settings xcuserdata/ -## Obj-C/Swift specific -*.hmap +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout -## App packaging -*.ipa -*.dSYM.zip -*.dSYM +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 -## Playgrounds -timeline.xctimeline -playground.xcworkspace +### Xcode Patch ### +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcworkspace/contents.xcworkspacedata +/*.gcno -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved -# *.xcodeproj -# -# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata -# hence it is not needed unless you have added a package configuration file to your project -# .swiftpm +### Projects ### +*.xcodeproj +*.xcworkspace -.build/ +### Tuist derived files ### +graph.dot +Derived/ -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ -# -# Add this line if you want to avoid checking in source code from the Xcode workspace -# *.xcworkspace - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build/ - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. -# Instead, use fastlane to re-generate the screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output +### Tuist managed dependencies ### +Tuist/.build \ No newline at end of file diff --git a/Projects/App/Info.plist b/Projects/App/Info.plist new file mode 100644 index 0000000..c60398b --- /dev/null +++ b/Projects/App/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + UILaunchStoryboardName + LaunchScreen + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSExceptionAllowsInsecureHTTPLoads + + NSExceptionMinimumTLSVersion + TLSv1.2 + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + + \ No newline at end of file diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift new file mode 100644 index 0000000..f8b5530 --- /dev/null +++ b/Projects/App/Project.swift @@ -0,0 +1,55 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let moduleName = "App" + +let dependecies: [TargetDependency] = [] + +let testDependencies: [TargetDependency] = [ + .target(name: moduleName), +] + +let project = Project( + name: moduleName, + options: .options(automaticSchemesOptions: .disabled), + settings: .settings( + base: commonSettings + ), + targets: [ + .target(name: moduleName, + destinations: .iOS, + product: .app, + bundleId: "com.vrc.exchanges.\(moduleName.lowercased())", + deploymentTargets: iOSDeploymentTarget, + infoPlist: "Info.plist", + buildableFolders: ["Sources", "Resources"], + dependencies: dependecies + ), + .target(name: "\(moduleName)Tests", + destinations: .iOS, + product: .unitTests, + bundleId: "com.vrc.exchanges.\(moduleName.lowercased()).tests", + deploymentTargets: iOSDeploymentTarget, + infoPlist: .default, + buildableFolders: ["Tests"], + dependencies: testDependencies), + .target(name: "\(moduleName)UITests", + destinations: .iOS, + product: .uiTests, + bundleId: "com.vrc.exchanges.\(moduleName.lowercased()).uitests", + deploymentTargets: iOSDeploymentTarget, + infoPlist: .default, + buildableFolders: ["UITests"], + dependencies: testDependencies + [.xctest]) + + ], + schemes: [ + .scheme(name: moduleName, + shared: true, + buildAction: .buildAction(targets: [.project(path: ".", target: moduleName)]), + testAction: .targets(["\(moduleName)Tests", "\(moduleName)UITests"]), + runAction: .runAction(configuration: .debug, + executable: .project(path: ".", target: moduleName), + arguments: .arguments(environmentVariables: developmentEnv))) + ] +) diff --git a/Projects/App/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/Projects/App/Resources/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Projects/App/Resources/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Projects/App/Resources/Assets.xcassets/Contents.json b/Projects/App/Resources/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Projects/App/Resources/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard b/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/App/Sources/AppDelegate.swift b/Projects/App/Sources/AppDelegate.swift new file mode 100644 index 0000000..04c8a2b --- /dev/null +++ b/Projects/App/Sources/AppDelegate.swift @@ -0,0 +1,24 @@ +// +// AppDelegate.swift +// ExchangesApp +// +// Created by Vitor Conceicao on 06/02/26. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + } +} diff --git a/Projects/App/Sources/SceneDelegate.swift b/Projects/App/Sources/SceneDelegate.swift new file mode 100644 index 0000000..6f8da53 --- /dev/null +++ b/Projects/App/Sources/SceneDelegate.swift @@ -0,0 +1,36 @@ +// +// SceneDelegate.swift +// ExchangesApp +// +// Created by Vitor Conceicao on 06/02/26. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = (scene as? UIWindowScene) else { + return + } + + let window = UIWindow(windowScene: windowScene) + let nav = UINavigationController(rootViewController: ViewController()) + window.rootViewController = nav + window.makeKeyAndVisible() + self.window = window + } + + func sceneDidDisconnect(_ scene: UIScene) {} + + func sceneDidBecomeActive(_ scene: UIScene) {} + + func sceneWillResignActive(_ scene: UIScene) {} + + func sceneWillEnterForeground(_ scene: UIScene) {} + + func sceneDidEnterBackground(_ scene: UIScene) {} +} + diff --git a/Projects/App/Sources/ViewController.swift b/Projects/App/Sources/ViewController.swift new file mode 100644 index 0000000..8ee1793 --- /dev/null +++ b/Projects/App/Sources/ViewController.swift @@ -0,0 +1,16 @@ +// +// ViewController.swift +// ExchangesApp +// +// Created by Vitor Conceicao on 06/02/26. +// + +import UIKit + +class ViewController: UIViewController { + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + view.backgroundColor = .blue + } +} diff --git a/Projects/App/Tests/ExchangesAppTests.swift b/Projects/App/Tests/ExchangesAppTests.swift new file mode 100644 index 0000000..36bcd27 --- /dev/null +++ b/Projects/App/Tests/ExchangesAppTests.swift @@ -0,0 +1,17 @@ +// +// ExchangesAppTests.swift +// ExchangesAppTests +// +// Created by Vitor Conceicao on 06/02/26. +// + +import Testing +@testable import App + +struct ExchangesAppTests { + + @Test func example() async throws { + #expect(true == true) + } + +} diff --git a/Projects/App/UITests/ExchangesAppUITests.swift b/Projects/App/UITests/ExchangesAppUITests.swift new file mode 100644 index 0000000..ba4bdd9 --- /dev/null +++ b/Projects/App/UITests/ExchangesAppUITests.swift @@ -0,0 +1,41 @@ +// +// ExchangesAppUITests.swift +// ExchangesAppUITests +// +// Created by Vitor Conceicao on 06/02/26. +// + +import XCTest + +final class ExchangesAppUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/Projects/App/UITests/ExchangesAppUITestsLaunchTests.swift b/Projects/App/UITests/ExchangesAppUITestsLaunchTests.swift new file mode 100644 index 0000000..73c7b30 --- /dev/null +++ b/Projects/App/UITests/ExchangesAppUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// ExchangesAppUITestsLaunchTests.swift +// ExchangesAppUITests +// +// Created by Vitor Conceicao on 06/02/26. +// + +import XCTest + +final class ExchangesAppUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/Tuist/Package.swift b/Tuist/Package.swift new file mode 100644 index 0000000..c797f6a --- /dev/null +++ b/Tuist/Package.swift @@ -0,0 +1,15 @@ +// swift-tools-version: 5.9 +import PackageDescription + +#if TUIST + import ProjectDescription + + let packageSettings = PackageSettings( + productTypes: [:] + ) +#endif + +let package = Package( + name: "ExchangesApp", + dependencies: [] +) \ No newline at end of file diff --git a/Tuist/ProjectDescriptionHelpers/Project+Template.swift b/Tuist/ProjectDescriptionHelpers/Project+Template.swift new file mode 100644 index 0000000..c36ad61 --- /dev/null +++ b/Tuist/ProjectDescriptionHelpers/Project+Template.swift @@ -0,0 +1,113 @@ +import ProjectDescription + +public enum ModuleTargets: Equatable { + case test, testing, interfaces, app, source +} + +let cmApiBaseURL = EnvironmentVariable(stringLiteral: "https://pro-api.coinmarketcap.com") + +public let developmentEnv: [String: EnvironmentVariable] = [ + "CM_API_BASE_URL": cmApiBaseURL, +] + +public let iOSDeploymentTarget: DeploymentTargets = .iOS("14.0") +public let commonSettings: SettingsDictionary = [ + "SWIFT_VERSION": "6.0" +] + +public extension Project { + static func templateModule(named moduleName: String, + targets: [ModuleTargets] = [.source, .interfaces, .test], + dependencies: [TargetDependency] = [], + testDependencies: [TargetDependency] = [], + shouldSetEnvVars: Bool = false) -> Project { + var selectedTargets: [Target] = [] + + if targets.contains(.interfaces) { + selectedTargets.append( + .target(name: "\(moduleName)Interfaces", + destinations: .iOS, + product: .framework, + bundleId: "com.vrc.\(moduleName.lowercased()).interfaces", + deploymentTargets: iOSDeploymentTarget, + infoPlist: .default, + sources: ["Interfaces/**"]) + ) + } + + var moduleTargets: [TargetDependency] = dependencies + + if targets.contains(.interfaces) { + moduleTargets.append(.target(name: "\(moduleName)Interfaces")) + } + + if targets.contains(.source) { + selectedTargets.append( + .target(name: moduleName, + destinations: .iOS, + product: .framework, + bundleId: "com.vrc.\(moduleName.lowercased())", + deploymentTargets: iOSDeploymentTarget, + infoPlist: .default, + sources: ["Sources/**"], + dependencies: moduleTargets) + ) + } + + if targets.contains(.test) { + var testDeps: [TargetDependency] = testDependencies + testDeps.append(.target(name: moduleName)) + + if targets.contains(.testing) { + testDeps.append(.target(name: "\(moduleName)Testing")) + } + + selectedTargets.append( + .target(name: "\(moduleName)Tests", + destinations: .iOS, + product: .unitTests, + bundleId: "com.vrc.\(moduleName.lowercased()).tests", + deploymentTargets: iOSDeploymentTarget, + infoPlist: .default, + sources: ["Tests/**"], + dependencies: testDeps) + ) + } + + if targets.contains(.testing) && targets.contains(.interfaces) { + selectedTargets.append( + .target(name: "\(moduleName)Testing", + destinations: .iOS, + product: .framework, + bundleId: "com.vrc.\(moduleName.lowercased()).testing", + deploymentTargets: iOSDeploymentTarget, + infoPlist: .default, + sources: ["Testing/**"], + dependencies: [ + .target(name: "\(moduleName)Interfaces") + ]) + ) + } + + return Project( + name: moduleName, + options: .options(automaticSchemesOptions: .disabled), + settings: .settings( + base: commonSettings + ), + targets: selectedTargets, + schemes: [ + .scheme( + name: moduleName, + shared: true, + buildAction: .buildAction(targets: ["\(moduleName)"]), + testAction: targets.contains(.test) ? .targets(["\(moduleName)Tests"]) : nil, + runAction: .runAction( + configuration: .debug, + arguments: shouldSetEnvVars ? .arguments(environmentVariables: developmentEnv) : nil + ) + ) + ] + ) + } +} diff --git a/Workspace.swift b/Workspace.swift new file mode 100644 index 0000000..b2f29eb --- /dev/null +++ b/Workspace.swift @@ -0,0 +1,11 @@ +import Foundation +import ProjectDescription + +let workspace = Workspace( + name: "ExchangesApp", + projects: [ + "./Projects/App", + ], + schemes: [], + generationOptions: .options(autogeneratedWorkspaceSchemes: .disabled) +) From 0af0867d483f9f72f7184a371f5dd933efa58654 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Sat, 7 Feb 2026 16:11:50 -0300 Subject: [PATCH 04/16] feat: swiftlint (#18) --- .github/pull_request_template.md | 10 + .swiftlint.yml | 4 + Gemfile.lock | 240 ++++++++++++++++++ Projects/App/Project.swift | 3 + .../Project+Template.swift | 18 +- scripts/swiftlint.sh | 14 + 6 files changed, 285 insertions(+), 4 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100755 .swiftlint.yml create mode 100644 Gemfile.lock create mode 100755 scripts/swiftlint.sh diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..baf247f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,10 @@ +## Description + + +## Type of Change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Refactor (no functional changes) +- [ ] Test update \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100755 index 0000000..6c36a9e --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,4 @@ +excluded: + - "**/Tests" + - "**/UITests" + - "**/Project.swift" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..c926294 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,240 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.8) + abbrev (0.1.2) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) + artifactory (3.0.17) + atomos (0.1.3) + aws-eventstream (1.4.0) + aws-partitions (1.1213.0) + aws-sdk-core (3.242.0) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.992.0) + aws-sigv4 (~> 1.9) + base64 + bigdecimal + jmespath (~> 1, >= 1.6.1) + logger + aws-sdk-kms (1.121.0) + aws-sdk-core (~> 3, >= 3.241.4) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.213.0) + aws-sdk-core (~> 3, >= 3.241.4) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.5) + aws-sigv4 (1.12.1) + aws-eventstream (~> 1, >= 1.0.2) + babosa (1.0.4) + base64 (0.2.0) + benchmark (0.5.0) + bigdecimal (4.0.1) + claide (1.1.0) + colored (1.2) + colored2 (3.1.2) + commander (4.6.0) + highline (~> 2.0.0) + csv (3.3.5) + declarative (0.0.20) + digest-crc (0.7.0) + rake (>= 12.0.0, < 14.0.0) + domain_name (0.6.20240107) + dotenv (2.8.1) + emoji_regex (3.2.3) + excon (0.112.0) + faraday (1.10.4) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-cookie_jar (0.0.8) + faraday (>= 0.8.0) + http-cookie (>= 1.0.0) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.1) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.2.0) + multipart-post (~> 2.0) + faraday-net_http (1.0.2) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.1) + faraday (~> 1.0) + fastimage (2.4.0) + fastlane (2.232.0) + CFPropertyList (>= 2.3, < 4.0.0) + abbrev (~> 0.1.2) + addressable (>= 2.8, < 3.0.0) + artifactory (~> 3.0) + aws-sdk-s3 (~> 1.197) + babosa (>= 1.0.3, < 2.0.0) + base64 (~> 0.2.0) + benchmark (>= 0.1.0) + bundler (>= 1.17.3, < 5.0.0) + colored (~> 1.2) + commander (~> 4.6) + csv (~> 3.3) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 4.0) + excon (>= 0.71.0, < 1.0.0) + faraday (~> 1.0) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 1.0) + fastimage (>= 2.1.0, < 3.0.0) + fastlane-sirp (>= 1.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-apis-androidpublisher_v3 (~> 0.3) + google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-env (>= 1.6.0, <= 2.1.1) + google-cloud-storage (~> 1.31) + highline (~> 2.0) + http-cookie (~> 1.0.5) + json (< 3.0.0) + jwt (>= 2.1.0, < 3) + logger (>= 1.6, < 2.0) + mini_magick (>= 4.9.4, < 5.0.0) + multipart-post (>= 2.0.0, < 3.0.0) + mutex_m (~> 0.3.0) + naturally (~> 2.2) + nkf (~> 0.2.0) + optparse (>= 0.1.1, < 1.0.0) + ostruct (>= 0.1.0) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 2.0.0, < 3.0.0) + security (= 0.1.5) + simctl (~> 1.6.3) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (~> 3) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.13.0, < 2.0.0) + xcpretty (~> 0.4.1) + xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) + fastlane-sirp (1.0.0) + sysrandom (~> 1.0) + gh_inspector (1.1.3) + google-apis-androidpublisher_v3 (0.95.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-core (0.18.0) + addressable (~> 2.5, >= 2.5.1) + googleauth (~> 1.9) + httpclient (>= 2.8.3, < 3.a) + mini_mime (~> 1.0) + mutex_m + representable (~> 3.0) + retriable (>= 2.0, < 4.a) + google-apis-iamcredentials_v1 (0.26.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-playcustomapp_v1 (0.17.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-storage_v1 (0.59.0) + google-apis-core (>= 0.15.0, < 2.a) + google-cloud-core (1.8.0) + google-cloud-env (>= 1.0, < 3.a) + google-cloud-errors (~> 1.0) + google-cloud-env (2.1.1) + faraday (>= 1.0, < 3.a) + google-cloud-errors (1.5.0) + google-cloud-storage (1.58.0) + addressable (~> 2.8) + digest-crc (~> 0.4) + google-apis-core (>= 0.18, < 2) + google-apis-iamcredentials_v1 (~> 0.18) + google-apis-storage_v1 (>= 0.42) + google-cloud-core (~> 1.6) + googleauth (~> 1.9) + mini_mime (~> 1.0) + googleauth (1.11.2) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.1) + jwt (>= 1.4, < 3.0) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + highline (2.0.3) + http-cookie (1.0.8) + domain_name (~> 0.5) + httpclient (2.9.0) + mutex_m + jmespath (1.6.2) + json (2.18.1) + jwt (2.10.2) + base64 + logger (1.7.0) + mini_magick (4.13.2) + mini_mime (1.1.5) + multi_json (1.19.1) + multipart-post (2.4.1) + mutex_m (0.3.0) + nanaimo (0.4.0) + naturally (2.3.0) + nkf (0.2.0) + optparse (0.8.1) + os (1.1.4) + ostruct (0.6.3) + plist (3.7.2) + public_suffix (7.0.2) + rake (13.3.1) + representable (3.2.0) + declarative (< 0.1.0) + trailblazer-option (>= 0.1.1, < 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rexml (3.4.4) + rouge (3.28.0) + ruby2_keywords (0.0.5) + rubyzip (2.4.1) + security (0.1.5) + signet (0.21.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 4.0) + multi_json (~> 1.10) + simctl (1.6.10) + CFPropertyList + naturally + sysrandom (1.0.5) + terminal-notifier (2.0.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + trailblazer-option (0.1.2) + tty-cursor (0.7.1) + tty-screen (0.8.2) + tty-spinner (0.9.3) + tty-cursor (~> 0.7) + uber (0.1.0) + unicode-display_width (2.6.0) + word_wrap (1.0.0) + xcodeproj (1.27.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) + xcpretty (0.4.1) + rouge (~> 3.28.0) + xcpretty-travis-formatter (1.0.1) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + arm64-darwin-24 + ruby + +DEPENDENCIES + fastlane (~> 2.232.0) + +BUNDLED WITH + 2.6.7 diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index f8b5530..ad95006 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -23,6 +23,9 @@ let project = Project( deploymentTargets: iOSDeploymentTarget, infoPlist: "Info.plist", buildableFolders: ["Sources", "Resources"], + scripts: [ + swiftLintScript + ], dependencies: dependecies ), .target(name: "\(moduleName)Tests", diff --git a/Tuist/ProjectDescriptionHelpers/Project+Template.swift b/Tuist/ProjectDescriptionHelpers/Project+Template.swift index c36ad61..1ec920b 100644 --- a/Tuist/ProjectDescriptionHelpers/Project+Template.swift +++ b/Tuist/ProjectDescriptionHelpers/Project+Template.swift @@ -15,6 +15,10 @@ public let commonSettings: SettingsDictionary = [ "SWIFT_VERSION": "6.0" ] +public let swiftLintScript: TargetScript = .post(path: "../../scripts/swiftlint.sh", + arguments: "", + name: "Swiftlint") + public extension Project { static func templateModule(named moduleName: String, targets: [ModuleTargets] = [.source, .interfaces, .test], @@ -31,7 +35,10 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased()).interfaces", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - sources: ["Interfaces/**"]) + buildableFolders: ["Interfaces/**"], + scripts: [ + swiftLintScript + ]) ) } @@ -49,7 +56,10 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased())", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - sources: ["Sources/**"], + buildableFolders: ["Sources/**"], + scripts: [ + swiftLintScript + ], dependencies: moduleTargets) ) } @@ -69,7 +79,7 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased()).tests", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - sources: ["Tests/**"], + buildableFolders: ["Tests/**"], dependencies: testDeps) ) } @@ -82,7 +92,7 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased()).testing", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - sources: ["Testing/**"], + buildableFolders: ["Testing/**"] , dependencies: [ .target(name: "\(moduleName)Interfaces") ]) diff --git a/scripts/swiftlint.sh b/scripts/swiftlint.sh new file mode 100755 index 0000000..c147eb1 --- /dev/null +++ b/scripts/swiftlint.sh @@ -0,0 +1,14 @@ +CONFIG_PATH="$SRCROOT/../../.swiftlint.yml" + +if [[ "$(uname -m)" == arm64 ]] +then + export PATH="/opt/homebrew/bin:$PATH" +fi + +if command -v swiftlint >/dev/null 2>&1 +then + swiftlint --config "$CONFIG_PATH" + # swiftlint +else + echo "warning: `swiftlint` command not found - See https://github.com/realm/SwiftLint#installation for installation instructions." +fi \ No newline at end of file From be8af6036ae3c711d690a810daf10eea6400ed08 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Sat, 7 Feb 2026 22:54:27 -0300 Subject: [PATCH 05/16] feat: pull request lane (#19) --- .github/pull_request_template.md | 2 +- .github/workflows/pr_status.yml | 107 ++++++++- .gitignore | 9 +- Brewfile | 3 +- Dangerfile | 27 +++ Gemfile | 7 +- Gemfile.lock | 240 --------------------- Projects/App/Project.swift | 7 +- Projects/App/Tests/ExchangesAppTests.swift | 3 +- fastlane/Appfile | 6 + fastlane/Fastfile | 47 ++++ scripts/ci-setup.sh | 1 + scripts/local-setup.sh | 1 + 13 files changed, 211 insertions(+), 249 deletions(-) create mode 100644 Dangerfile delete mode 100644 Gemfile.lock create mode 100644 fastlane/Appfile create mode 100644 fastlane/Fastfile diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index baf247f..1c4f673 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,5 @@ ## Description - +Description ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index ff452f9..8d8411d 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -4,10 +4,44 @@ on: pull_request: branches: [ "develop", "main" ] -jobs: +jobs: + paths-filter: + name: Verify targets to run tests + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.matrix.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - name: Check for file changes + uses: dorny/paths-filter@v2 + id: filter + with: + filters: | + app: + - 'Projects/App/**' + - name: Generate matrix + id: matrix + run: | + targets=() + if [ "${{ steps.filter.outputs.app }}" == "true" ]; then + targets+=("App") + fi + + if [ ${#targets[@]} -gt 0 ]; then + matrix="{\"target\": [$(printf '"%s",' "${targets[@]}" | sed 's/,$//')]}" + else + matrix='{"target": []}' + fi + echo "matrix=$matrix" >> $GITHUB_OUTPUT + test: - name: Setup project + name: Test ${{ matrix.target }} runs-on: macos-26 + needs: paths-filter + if: fromJson(needs.paths-filter.outputs.matrix).target[0] != null + strategy: + matrix: ${{ fromJson(needs.paths-filter.outputs.matrix) }} permissions: pull-requests: write issues: write @@ -19,4 +53,73 @@ jobs: - name: Install dependencies run: tuist install - name: Generate project + run: tuist generate --no-open + - name: Run tests for ${{ matrix.target }} + run: exec fastlane tests target:${{ matrix.target }} + - name: Generate code coverage + run: fastlane tests_coverage target:${{ matrix.target }} + - name: Zip reports + run: zip -r reports-${{ matrix.target }}.zip reports-${{ matrix.target }}/test_output/ + - name: Upload test reports + uses: actions/upload-artifact@v4 + with: + name: test-reports-${{ matrix.target }} + path: reports-${{ matrix.target }}.zip + + danger: + name: Danger Code Review + runs-on: ubuntu-latest + needs: [test] + if: always() + permissions: + pull-requests: write + contents: read + statuses: write + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 100 + - name: Download All Coverage Artifacts + uses: actions/download-artifact@v4 + with: + path: all-reports + pattern: test-reports-* + merge-multiple: true + - name: Unzip reports + run: cd all-reports && unzip "*.zip" + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2' + bundler-with: local + - uses: actions/cache@v4 + with: + path: vendor/bundle + key: ${{ runner.os }}-gems-${{ hashFiles('Gemfile') }} # change your gemfile path + restore-keys: | + ${{ runner.os }}-gems- + - name: Run Danger + uses: MeilCli/danger-action@v6 + with: + plugins_file: 'Gemfile' + install_path: 'vendor/bundle' + danger_file: 'Dangerfile' + danger_id: 'danger-pr' + env: + DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + check-project: + name: Check project generation + runs-on: macos-26 + needs: paths-filter + if: fromJson(needs.paths-filter.outputs.matrix).target[0] == null + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - name: CI Setup + run: make ci-setup + - name: Install dependencies + run: tuist install + - name: Check project generation run: tuist generate --no-open \ No newline at end of file diff --git a/.gitignore b/.gitignore index 24b244f..b20b7ae 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,11 @@ graph.dot Derived/ ### Tuist managed dependencies ### -Tuist/.build \ No newline at end of file +Tuist/.build + +fastlane/report.xml +fastlane/README.md +test_output +derived_data +Gemfile.lock +.bundle \ No newline at end of file diff --git a/Brewfile b/Brewfile index 47139da..fad43d8 100644 --- a/Brewfile +++ b/Brewfile @@ -1,4 +1,5 @@ tap "tuist/tuist" brew "tuist" -brew "swiftlint" \ No newline at end of file +brew "swiftlint" +brew "xcbeautify" \ No newline at end of file diff --git a/Dangerfile b/Dangerfile new file mode 100644 index 0000000..e6e9410 --- /dev/null +++ b/Dangerfile @@ -0,0 +1,27 @@ +require 'rexml/document' + +# 1. Basic PR checks +warn("PR is still Work in Progress") if github.pr_title.include?("WIP") + +# 2. Report Coverage +coverage_folder = "all-reports" + +Dir.glob("#{coverage_folder}/reports-*/test_output/cobertura.xml").each do |xml_file| + target_name = xml_file.match(/reports-(.+?)\//)[1] + doc = REXML::Document.new(File.read(xml_file)) + coverage_element = doc.root + overall_rate = coverage_element.attributes["line-rate"].to_f + overall_percentage = (overall_rate * 100).to_i + message("Code coverage for #{target_name}: #{overall_percentage}%") + warn("Code coverage for #{target_name} is below 80%: #{overall_percentage}%") if overall_rate < 0.8 + + # Build table for files + table = "| File | Coverage |\n|------|----------|\n" + doc.elements.each("//class") do |cls| + file_name = cls.attributes["name"] + line_rate = cls.attributes["line-rate"].to_f + file_percentage = (line_rate * 100).to_i + table += "| #{file_name} | #{file_percentage}% |\n" + end + markdown("### Coverage Details for #{target_name}\n#{table}") +end \ No newline at end of file diff --git a/Gemfile b/Gemfile index 37ef80d..6c98236 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,8 @@ source "https://rubygems.org" -gem "fastlane", "~> 2.232.0" \ No newline at end of file +gem "fastlane", "~> 2.232.0" +gem 'slather', "~> 2.8.5" + +group :local do + gem 'danger' +end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index c926294..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,240 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - CFPropertyList (3.0.8) - abbrev (0.1.2) - addressable (2.8.8) - public_suffix (>= 2.0.2, < 8.0) - artifactory (3.0.17) - atomos (0.1.3) - aws-eventstream (1.4.0) - aws-partitions (1.1213.0) - aws-sdk-core (3.242.0) - aws-eventstream (~> 1, >= 1.3.0) - aws-partitions (~> 1, >= 1.992.0) - aws-sigv4 (~> 1.9) - base64 - bigdecimal - jmespath (~> 1, >= 1.6.1) - logger - aws-sdk-kms (1.121.0) - aws-sdk-core (~> 3, >= 3.241.4) - aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.213.0) - aws-sdk-core (~> 3, >= 3.241.4) - aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.5) - aws-sigv4 (1.12.1) - aws-eventstream (~> 1, >= 1.0.2) - babosa (1.0.4) - base64 (0.2.0) - benchmark (0.5.0) - bigdecimal (4.0.1) - claide (1.1.0) - colored (1.2) - colored2 (3.1.2) - commander (4.6.0) - highline (~> 2.0.0) - csv (3.3.5) - declarative (0.0.20) - digest-crc (0.7.0) - rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20240107) - dotenv (2.8.1) - emoji_regex (3.2.3) - excon (0.112.0) - faraday (1.10.4) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) - ruby2_keywords (>= 0.0.4) - faraday-cookie_jar (0.0.8) - faraday (>= 0.8.0) - http-cookie (>= 1.0.0) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.1) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) - faraday-multipart (1.2.0) - multipart-post (~> 2.0) - faraday-net_http (1.0.2) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - faraday_middleware (1.2.1) - faraday (~> 1.0) - fastimage (2.4.0) - fastlane (2.232.0) - CFPropertyList (>= 2.3, < 4.0.0) - abbrev (~> 0.1.2) - addressable (>= 2.8, < 3.0.0) - artifactory (~> 3.0) - aws-sdk-s3 (~> 1.197) - babosa (>= 1.0.3, < 2.0.0) - base64 (~> 0.2.0) - benchmark (>= 0.1.0) - bundler (>= 1.17.3, < 5.0.0) - colored (~> 1.2) - commander (~> 4.6) - csv (~> 3.3) - dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 4.0) - excon (>= 0.71.0, < 1.0.0) - faraday (~> 1.0) - faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 1.0) - fastimage (>= 2.1.0, < 3.0.0) - fastlane-sirp (>= 1.0.0) - gh_inspector (>= 1.1.2, < 2.0.0) - google-apis-androidpublisher_v3 (~> 0.3) - google-apis-playcustomapp_v1 (~> 0.1) - google-cloud-env (>= 1.6.0, <= 2.1.1) - google-cloud-storage (~> 1.31) - highline (~> 2.0) - http-cookie (~> 1.0.5) - json (< 3.0.0) - jwt (>= 2.1.0, < 3) - logger (>= 1.6, < 2.0) - mini_magick (>= 4.9.4, < 5.0.0) - multipart-post (>= 2.0.0, < 3.0.0) - mutex_m (~> 0.3.0) - naturally (~> 2.2) - nkf (~> 0.2.0) - optparse (>= 0.1.1, < 1.0.0) - ostruct (>= 0.1.0) - plist (>= 3.1.0, < 4.0.0) - rubyzip (>= 2.0.0, < 3.0.0) - security (= 0.1.5) - simctl (~> 1.6.3) - terminal-notifier (>= 2.0.0, < 3.0.0) - terminal-table (~> 3) - tty-screen (>= 0.6.3, < 1.0.0) - tty-spinner (>= 0.8.0, < 1.0.0) - word_wrap (~> 1.0.0) - xcodeproj (>= 1.13.0, < 2.0.0) - xcpretty (~> 0.4.1) - xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - fastlane-sirp (1.0.0) - sysrandom (~> 1.0) - gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.95.0) - google-apis-core (>= 0.15.0, < 2.a) - google-apis-core (0.18.0) - addressable (~> 2.5, >= 2.5.1) - googleauth (~> 1.9) - httpclient (>= 2.8.3, < 3.a) - mini_mime (~> 1.0) - mutex_m - representable (~> 3.0) - retriable (>= 2.0, < 4.a) - google-apis-iamcredentials_v1 (0.26.0) - google-apis-core (>= 0.15.0, < 2.a) - google-apis-playcustomapp_v1 (0.17.0) - google-apis-core (>= 0.15.0, < 2.a) - google-apis-storage_v1 (0.59.0) - google-apis-core (>= 0.15.0, < 2.a) - google-cloud-core (1.8.0) - google-cloud-env (>= 1.0, < 3.a) - google-cloud-errors (~> 1.0) - google-cloud-env (2.1.1) - faraday (>= 1.0, < 3.a) - google-cloud-errors (1.5.0) - google-cloud-storage (1.58.0) - addressable (~> 2.8) - digest-crc (~> 0.4) - google-apis-core (>= 0.18, < 2) - google-apis-iamcredentials_v1 (~> 0.18) - google-apis-storage_v1 (>= 0.42) - google-cloud-core (~> 1.6) - googleauth (~> 1.9) - mini_mime (~> 1.0) - googleauth (1.11.2) - faraday (>= 1.0, < 3.a) - google-cloud-env (~> 2.1) - jwt (>= 1.4, < 3.0) - multi_json (~> 1.11) - os (>= 0.9, < 2.0) - signet (>= 0.16, < 2.a) - highline (2.0.3) - http-cookie (1.0.8) - domain_name (~> 0.5) - httpclient (2.9.0) - mutex_m - jmespath (1.6.2) - json (2.18.1) - jwt (2.10.2) - base64 - logger (1.7.0) - mini_magick (4.13.2) - mini_mime (1.1.5) - multi_json (1.19.1) - multipart-post (2.4.1) - mutex_m (0.3.0) - nanaimo (0.4.0) - naturally (2.3.0) - nkf (0.2.0) - optparse (0.8.1) - os (1.1.4) - ostruct (0.6.3) - plist (3.7.2) - public_suffix (7.0.2) - rake (13.3.1) - representable (3.2.0) - declarative (< 0.1.0) - trailblazer-option (>= 0.1.1, < 0.2.0) - uber (< 0.2.0) - retriable (3.1.2) - rexml (3.4.4) - rouge (3.28.0) - ruby2_keywords (0.0.5) - rubyzip (2.4.1) - security (0.1.5) - signet (0.21.0) - addressable (~> 2.8) - faraday (>= 0.17.5, < 3.a) - jwt (>= 1.5, < 4.0) - multi_json (~> 1.10) - simctl (1.6.10) - CFPropertyList - naturally - sysrandom (1.0.5) - terminal-notifier (2.0.0) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - trailblazer-option (0.1.2) - tty-cursor (0.7.1) - tty-screen (0.8.2) - tty-spinner (0.9.3) - tty-cursor (~> 0.7) - uber (0.1.0) - unicode-display_width (2.6.0) - word_wrap (1.0.0) - xcodeproj (1.27.0) - CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.3) - claide (>= 1.0.2, < 2.0) - colored2 (~> 3.1) - nanaimo (~> 0.4.0) - rexml (>= 3.3.6, < 4.0) - xcpretty (0.4.1) - rouge (~> 3.28.0) - xcpretty-travis-formatter (1.0.1) - xcpretty (~> 0.2, >= 0.0.7) - -PLATFORMS - arm64-darwin-24 - ruby - -DEPENDENCIES - fastlane (~> 2.232.0) - -BUNDLED WITH - 2.6.7 diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index ad95006..7fd096c 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -50,7 +50,12 @@ let project = Project( .scheme(name: moduleName, shared: true, buildAction: .buildAction(targets: [.project(path: ".", target: moduleName)]), - testAction: .targets(["\(moduleName)Tests", "\(moduleName)UITests"]), + testAction: .targets([ + "\(moduleName)Tests", + // Disabled UITests for now, as they are not yet implemented +// "\(moduleName)UITests" + ] + ), runAction: .runAction(configuration: .debug, executable: .project(path: ".", target: moduleName), arguments: .arguments(environmentVariables: developmentEnv))) diff --git a/Projects/App/Tests/ExchangesAppTests.swift b/Projects/App/Tests/ExchangesAppTests.swift index 36bcd27..88bd0fa 100644 --- a/Projects/App/Tests/ExchangesAppTests.swift +++ b/Projects/App/Tests/ExchangesAppTests.swift @@ -8,10 +8,9 @@ import Testing @testable import App +@Suite struct ExchangesAppTests { - @Test func example() async throws { #expect(true == true) } - } diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 0000000..4282947 --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1,6 @@ +# app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app +# apple_id("[[APPLE_ID]]") # Your Apple Developer Portal username + + +# For more information about the Appfile, see: +# https://docs.fastlane.tools/advanced/#appfile diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 0000000..78b744a --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,47 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:ios) + +platform :ios do + desc "Run Unit tests" + lane :tests do |options| + target = options[:target] || "App" + + run_tests(workspace: "ExchangesApp.xcworkspace", + device: "iPhone 17 (26.1)", + scheme: target, + code_coverage: true, + derived_data_path: "reports-#{target}/derived_data", + output_directory: "reports-#{target}/test_output",) + end + + lane :tests_coverage do |options| + target = options[:target] || "App" + slather( + proj: "Projects/#{target}/#{target}.xcodeproj", + scheme: target, + input_format: "profdata", + build_directory: "reports-#{target}/derived_data", + output_directory: "reports-#{target}/test_output", + source_directory: "Projects", + ignore: [ + "**/Derived/**", + "**/derived_data/**" + ], + cobertura_xml: true + ) + end +end diff --git a/scripts/ci-setup.sh b/scripts/ci-setup.sh index 1e85015..ddde264 100644 --- a/scripts/ci-setup.sh +++ b/scripts/ci-setup.sh @@ -8,6 +8,7 @@ brew bundle install echo "✅ Brew dependencies installed." echo "Installing Bundles..." +bundle config set without local bundle install echo "✅ Bundles installed." diff --git a/scripts/local-setup.sh b/scripts/local-setup.sh index ac891f8..d920983 100644 --- a/scripts/local-setup.sh +++ b/scripts/local-setup.sh @@ -22,6 +22,7 @@ brew bundle install echo "✅ Brew dependencies installed." echo "Installing Bundles..." +bundle config set with local bundle install echo "✅ Bundles installed." From 1799cd9d149126dac21732dd4ba63199ccbffe96 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Sun, 8 Feb 2026 09:38:07 -0300 Subject: [PATCH 06/16] feat: dependency injection module (#21) --- .github/workflows/pr_status.yml | 6 ++ .gitignore | 3 +- Dangerfile | 17 +++++- Projects/App/Project.swift | 7 ++- Projects/App/Sources/AppDelegate.swift | 24 -------- .../App/Sources/Application/AppDelegate.swift | 39 ++++++++++++ .../{ => Application}/SceneDelegate.swift | 9 ++- .../Tests/Application/AppDelegateTests.swift | 22 +++++++ Projects/App/Tests/ExchangesAppTests.swift | 16 ----- .../Interfaces/DependencyInjector.swift | 21 +++++++ .../Interfaces/DependencyResolver.swift | 18 ++++++ .../Interfaces/SharedContainer.swift | 29 +++++++++ Projects/DependencyInjection/Project.swift | 12 ++++ .../Sources/Injector.swift | 57 ++++++++++++++++++ .../Tests/Doubles/MockDependentService.swift | 17 ++++++ .../Tests/Doubles/MockService.swift | 24 ++++++++ .../Tests/InjectorTests.swift | 60 +++++++++++++++++++ Tuist/Package.resolved | 14 +++++ Tuist/Package.swift | 4 +- .../Project+Template.swift | 8 +-- Workspace.swift | 1 + fastlane/Fastfile | 6 +- 22 files changed, 359 insertions(+), 55 deletions(-) delete mode 100644 Projects/App/Sources/AppDelegate.swift create mode 100644 Projects/App/Sources/Application/AppDelegate.swift rename Projects/App/Sources/{ => Application}/SceneDelegate.swift (82%) create mode 100644 Projects/App/Tests/Application/AppDelegateTests.swift delete mode 100644 Projects/App/Tests/ExchangesAppTests.swift create mode 100644 Projects/DependencyInjection/Interfaces/DependencyInjector.swift create mode 100644 Projects/DependencyInjection/Interfaces/DependencyResolver.swift create mode 100644 Projects/DependencyInjection/Interfaces/SharedContainer.swift create mode 100644 Projects/DependencyInjection/Project.swift create mode 100644 Projects/DependencyInjection/Sources/Injector.swift create mode 100644 Projects/DependencyInjection/Tests/Doubles/MockDependentService.swift create mode 100644 Projects/DependencyInjection/Tests/Doubles/MockService.swift create mode 100644 Projects/DependencyInjection/Tests/InjectorTests.swift create mode 100644 Tuist/Package.resolved diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index 8d8411d..eebde1a 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -20,6 +20,8 @@ jobs: filters: | app: - 'Projects/App/**' + dependency_injection: + - 'Projects/DependencyInjection/**' - name: Generate matrix id: matrix run: | @@ -27,6 +29,10 @@ jobs: if [ "${{ steps.filter.outputs.app }}" == "true" ]; then targets+=("App") fi + + if [ "${{ steps.filter.outputs.dependency_injection }}" == "true" ]; then + targets+=("DependencyInjection") + fi if [ ${#targets[@]} -gt 0 ]; then matrix="{\"target\": [$(printf '"%s",' "${targets[@]}" | sed 's/,$//')]}" diff --git a/.gitignore b/.gitignore index b20b7ae..867d74a 100644 --- a/.gitignore +++ b/.gitignore @@ -74,4 +74,5 @@ fastlane/README.md test_output derived_data Gemfile.lock -.bundle \ No newline at end of file +.bundle +reports-*/ \ No newline at end of file diff --git a/Dangerfile b/Dangerfile index e6e9410..3f3d73a 100644 --- a/Dangerfile +++ b/Dangerfile @@ -12,16 +12,29 @@ Dir.glob("#{coverage_folder}/reports-*/test_output/cobertura.xml").each do |xml_ coverage_element = doc.root overall_rate = coverage_element.attributes["line-rate"].to_f overall_percentage = (overall_rate * 100).to_i + message("Code coverage for #{target_name}: #{overall_percentage}%") warn("Code coverage for #{target_name} is below 80%: #{overall_percentage}%") if overall_rate < 0.8 # Build table for files table = "| File | Coverage |\n|------|----------|\n" + files_added = 0 + doc.elements.each("//class") do |cls| - file_name = cls.attributes["name"] + file_name = cls.attributes["filename"] + + # --- FILTRO ADICIONADO AQUI --- + # Verifica se o nome do arquivo termina com .swift + next unless file_name.end_with?(".swift") + line_rate = cls.attributes["line-rate"].to_f file_percentage = (line_rate * 100).to_i table += "| #{file_name} | #{file_percentage}% |\n" + files_added += 1 + end + + # Só imprime a tabela se houver arquivos Swift encontrados + if files_added > 0 + markdown("### Coverage Details for #{target_name}\n#{table}") end - markdown("### Coverage Details for #{target_name}\n#{table}") end \ No newline at end of file diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index 7fd096c..75fc026 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -3,7 +3,12 @@ import ProjectDescriptionHelpers let moduleName = "App" -let dependecies: [TargetDependency] = [] +let dependecies: [TargetDependency] = [ + .project(target: "DependencyInjection", + path: "../DependencyInjection"), + .project(target: "DependencyInjectionInterfaces", + path: "../DependencyInjection") +] let testDependencies: [TargetDependency] = [ .target(name: moduleName), diff --git a/Projects/App/Sources/AppDelegate.swift b/Projects/App/Sources/AppDelegate.swift deleted file mode 100644 index 04c8a2b..0000000 --- a/Projects/App/Sources/AppDelegate.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// AppDelegate.swift -// ExchangesApp -// -// Created by Vitor Conceicao on 06/02/26. -// - -import UIKit - -@main -class AppDelegate: UIResponder, UIApplicationDelegate { - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - return true - } - - // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - } -} diff --git a/Projects/App/Sources/Application/AppDelegate.swift b/Projects/App/Sources/Application/AppDelegate.swift new file mode 100644 index 0000000..2f123d2 --- /dev/null +++ b/Projects/App/Sources/Application/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// ExchangesApp +// +// Created by Vitor Conceicao on 06/02/26. +// + +import DependencyInjection +import DependencyInjectionInterfaces +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + override init() { + super.init() + setupDependencies() + } + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, + configurationForConnecting connectingSceneSession: UISceneSession, + options: UIScene.ConnectionOptions) -> UISceneConfiguration { + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {} + + @MainActor + private func setupDependencies() { + let injector = Injector() + SharedContainer.shared.setInjector(injector) + } +} diff --git a/Projects/App/Sources/SceneDelegate.swift b/Projects/App/Sources/Application/SceneDelegate.swift similarity index 82% rename from Projects/App/Sources/SceneDelegate.swift rename to Projects/App/Sources/Application/SceneDelegate.swift index 6f8da53..18a4ed2 100644 --- a/Projects/App/Sources/SceneDelegate.swift +++ b/Projects/App/Sources/Application/SceneDelegate.swift @@ -11,10 +11,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - guard let windowScene = (scene as? UIWindowScene) else { - return - } + func scene(_ scene: UIScene, + willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) let nav = UINavigationController(rootViewController: ViewController()) @@ -33,4 +33,3 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func sceneDidEnterBackground(_ scene: UIScene) {} } - diff --git a/Projects/App/Tests/Application/AppDelegateTests.swift b/Projects/App/Tests/Application/AppDelegateTests.swift new file mode 100644 index 0000000..bb6a59e --- /dev/null +++ b/Projects/App/Tests/Application/AppDelegateTests.swift @@ -0,0 +1,22 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import DependencyInjectionInterfaces +@testable import App + +@Suite +@MainActor +struct AppDelegateTests { + @Test("GIVEN AppDelegate initialize THEN it should set injector") + func example() async throws { + #expect(throws: Never.self) { + _ = SharedContainer.shared.resolver() + } + } +} diff --git a/Projects/App/Tests/ExchangesAppTests.swift b/Projects/App/Tests/ExchangesAppTests.swift deleted file mode 100644 index 88bd0fa..0000000 --- a/Projects/App/Tests/ExchangesAppTests.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// ExchangesAppTests.swift -// ExchangesAppTests -// -// Created by Vitor Conceicao on 06/02/26. -// - -import Testing -@testable import App - -@Suite -struct ExchangesAppTests { - @Test func example() async throws { - #expect(true == true) - } -} diff --git a/Projects/DependencyInjection/Interfaces/DependencyInjector.swift b/Projects/DependencyInjection/Interfaces/DependencyInjector.swift new file mode 100644 index 0000000..fe191e5 --- /dev/null +++ b/Projects/DependencyInjection/Interfaces/DependencyInjector.swift @@ -0,0 +1,21 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public protocol DependencyInjector: DependencyResolver { + func register( + _ serviceType: Service.Type, + factory: @escaping (DependencyResolver) -> Service + ) + + func register( + _ serviceType: Service.Type, + factory: @escaping (DependencyResolver, Argument) -> Service + ) +} diff --git a/Projects/DependencyInjection/Interfaces/DependencyResolver.swift b/Projects/DependencyInjection/Interfaces/DependencyResolver.swift new file mode 100644 index 0000000..76d1c7f --- /dev/null +++ b/Projects/DependencyInjection/Interfaces/DependencyResolver.swift @@ -0,0 +1,18 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public protocol DependencyResolver { + func resolve() -> Service + + func resolve( + _ serviceType: Service.Type, + argument: Argument + ) -> Service +} diff --git a/Projects/DependencyInjection/Interfaces/SharedContainer.swift b/Projects/DependencyInjection/Interfaces/SharedContainer.swift new file mode 100644 index 0000000..3fe908b --- /dev/null +++ b/Projects/DependencyInjection/Interfaces/SharedContainer.swift @@ -0,0 +1,29 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public final class SharedContainer { + @MainActor public static let shared = SharedContainer() + + private var injector: DependencyInjector? + + private init() {} + + public func setInjector(_ injector: DependencyInjector) { + self.injector = injector + } + + public func resolver() -> DependencyResolver { + guard let injector = injector else { + fatalError("Dependency Error: Injector not set in SharedContainer.") + } + + return injector + } +} diff --git a/Projects/DependencyInjection/Project.swift b/Projects/DependencyInjection/Project.swift new file mode 100644 index 0000000..134e69f --- /dev/null +++ b/Projects/DependencyInjection/Project.swift @@ -0,0 +1,12 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let moduleName = "DependencyInjection" + +let dependecies: [TargetDependency] = [ + .external(name: "Swinject", condition: nil), +] + +let project = Project.templateModule(named: moduleName, + targets: [.source,. interfaces, .test], + dependencies: dependecies) diff --git a/Projects/DependencyInjection/Sources/Injector.swift b/Projects/DependencyInjection/Sources/Injector.swift new file mode 100644 index 0000000..e9b4d93 --- /dev/null +++ b/Projects/DependencyInjection/Sources/Injector.swift @@ -0,0 +1,57 @@ +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import Swinject +import DependencyInjectionInterfaces + +public final class Injector: DependencyInjector { + private let container: Container + + public init() { + self.container = Container() + } + + public func register(_ serviceType: Service.Type, + factory: @escaping (DependencyResolver) -> Service) { + container.register(serviceType) { [unowned self] _ in + factory(self) + } + } + + public func register( + _ serviceType: Service.Type, + factory: @escaping (DependencyResolver, Argument) -> Service + ) { + container.register(serviceType) { [unowned self] (_, arg: Argument) in + factory(self, arg) + } + } + + public func resolve() -> Service { + guard let service = container.synchronize().resolve(Service.self) else { + fatalError("Dependency Error: No service of type \(Service.self) was registered.") + } + + return service + } + + public func resolve( + _ serviceType: Service.Type, + argument: Argument + ) -> Service { + guard let service = getSynchonizedResolver().resolve(Service.self, argument: argument) else { + fatalError("Dependency Error: No service of type \(Service.self) was registered.") + } + + return service + } + + private func getSynchonizedResolver() -> Resolver { + return container.synchronize() + } +} diff --git a/Projects/DependencyInjection/Tests/Doubles/MockDependentService.swift b/Projects/DependencyInjection/Tests/Doubles/MockDependentService.swift new file mode 100644 index 0000000..18bb092 --- /dev/null +++ b/Projects/DependencyInjection/Tests/Doubles/MockDependentService.swift @@ -0,0 +1,17 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +protocol DependentService { + var testService: TestService { get } +} + +struct MockDependentService: DependentService { + let testService: TestService +} diff --git a/Projects/DependencyInjection/Tests/Doubles/MockService.swift b/Projects/DependencyInjection/Tests/Doubles/MockService.swift new file mode 100644 index 0000000..910005c --- /dev/null +++ b/Projects/DependencyInjection/Tests/Doubles/MockService.swift @@ -0,0 +1,24 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +protocol TestService { + var value: String { get } +} + +struct MockService: TestService { + let value: String = "test" +} + +struct MockServiceWithParameter: TestService { + var value: String = "test args" + + let parameter: String + let secondParameter: String +} diff --git a/Projects/DependencyInjection/Tests/InjectorTests.swift b/Projects/DependencyInjection/Tests/InjectorTests.swift new file mode 100644 index 0000000..b57cd69 --- /dev/null +++ b/Projects/DependencyInjection/Tests/InjectorTests.swift @@ -0,0 +1,60 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import DependencyInjection +import DependencyInjectionInterfaces + +@Suite("DependencyInjector Tests") +final class DependencyInjectorTests { + + @Test("Test synchronous registration and resolution") + func testSyncRegistrationAndResolution() { + let injector = Injector() + + injector.register(TestService.self) { _ in + MockService() + } + + let service: TestService = injector.resolve() + #expect(service.value == "test") + } + + + @Test("Test nested dependency resolution") + func testNestedResolution() { + let injector = Injector() + + injector.register(TestService.self) { _ in + MockService() + } + + injector.register(DependentService.self) { resolver in + MockDependentService(testService: resolver.resolve()) + } + + let service: DependentService = injector.resolve() + #expect(service.testService.value == "test") + } + + @Test("Test register and resolution with argument") + func testRegisterAndResolutionWithArgument() { + let injector = Injector() + let args = ("param1", "param2") + + injector.register(TestService.self) { (_, arg: (String, String)) in + let (param1, param2) = arg + return MockServiceWithParameter(parameter: param1, secondParameter: param2) + } + + let service: TestService = injector.resolve(TestService.self, + argument: args) + + #expect(service.value == "test args") + } +} diff --git a/Tuist/Package.resolved b/Tuist/Package.resolved new file mode 100644 index 0000000..1c13632 --- /dev/null +++ b/Tuist/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "swinject", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Swinject/Swinject.git", + "state" : { + "revision" : "b685b549fe4d8ae265fc7a2f27d0789720425d69", + "version" : "2.10.0" + } + } + ], + "version" : 2 +} diff --git a/Tuist/Package.swift b/Tuist/Package.swift index c797f6a..593d390 100644 --- a/Tuist/Package.swift +++ b/Tuist/Package.swift @@ -11,5 +11,7 @@ import PackageDescription let package = Package( name: "ExchangesApp", - dependencies: [] + dependencies: [ + .package(url: "https://github.com/Swinject/Swinject.git", from: "2.9.1"), + ] ) \ No newline at end of file diff --git a/Tuist/ProjectDescriptionHelpers/Project+Template.swift b/Tuist/ProjectDescriptionHelpers/Project+Template.swift index 1ec920b..241da1b 100644 --- a/Tuist/ProjectDescriptionHelpers/Project+Template.swift +++ b/Tuist/ProjectDescriptionHelpers/Project+Template.swift @@ -35,7 +35,7 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased()).interfaces", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - buildableFolders: ["Interfaces/**"], + buildableFolders: ["Interfaces"], scripts: [ swiftLintScript ]) @@ -56,7 +56,7 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased())", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - buildableFolders: ["Sources/**"], + buildableFolders: ["Sources"], scripts: [ swiftLintScript ], @@ -79,7 +79,7 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased()).tests", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - buildableFolders: ["Tests/**"], + buildableFolders: ["Tests"], dependencies: testDeps) ) } @@ -92,7 +92,7 @@ public extension Project { bundleId: "com.vrc.\(moduleName.lowercased()).testing", deploymentTargets: iOSDeploymentTarget, infoPlist: .default, - buildableFolders: ["Testing/**"] , + buildableFolders: ["Testing"] , dependencies: [ .target(name: "\(moduleName)Interfaces") ]) diff --git a/Workspace.swift b/Workspace.swift index b2f29eb..b9c48c6 100644 --- a/Workspace.swift +++ b/Workspace.swift @@ -5,6 +5,7 @@ let workspace = Workspace( name: "ExchangesApp", projects: [ "./Projects/App", + "./Projects/DependencyInjection" ], schemes: [], generationOptions: .options(autogeneratedWorkspaceSchemes: .disabled) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 78b744a..e936b48 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -39,7 +39,11 @@ platform :ios do source_directory: "Projects", ignore: [ "**/Derived/**", - "**/derived_data/**" + "**/derived_data/**", + "**/Interfaces/**", + "**/Tests/**", + "**/Testing/**", + "Tuist/**", ], cobertura_xml: true ) From ce92f4148df5601171c41b20622f7b6f1faf8205 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:30:57 -0300 Subject: [PATCH 07/16] feat: design system module and component error view (#22) --- .github/workflows/pr_status.yml | 6 + Projects/DesignSystem/Project.swift | 15 ++ .../Sources/Components/ErrorView.swift | 144 ++++++++++++++++++ .../Sources/Constants/Spacings.swift | 20 +++ .../Sources/Protocols/ViewCode.swift | 28 ++++ .../Components/ErrorViewSnapshotTest.swift | 49 ++++++ .../testConfigureCode.1.png | Bin 0 -> 106810 bytes .../testConfigureDefaultValues.1.png | Bin 0 -> 103309 bytes Tuist/Package.resolved | 36 +++++ Tuist/Package.swift | 3 +- Workspace.swift | 3 +- 11 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 Projects/DesignSystem/Project.swift create mode 100644 Projects/DesignSystem/Sources/Components/ErrorView.swift create mode 100644 Projects/DesignSystem/Sources/Constants/Spacings.swift create mode 100644 Projects/DesignSystem/Sources/Protocols/ViewCode.swift create mode 100644 Projects/DesignSystem/Tests/Components/ErrorViewSnapshotTest.swift create mode 100644 Projects/DesignSystem/Tests/Components/__Snapshots__/ErrorViewSnapshotTest/testConfigureCode.1.png create mode 100644 Projects/DesignSystem/Tests/Components/__Snapshots__/ErrorViewSnapshotTest/testConfigureDefaultValues.1.png diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index eebde1a..15bf55b 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -22,6 +22,8 @@ jobs: - 'Projects/App/**' dependency_injection: - 'Projects/DependencyInjection/**' + design_system: + - 'Projects/DesignSystem/**' - name: Generate matrix id: matrix run: | @@ -33,6 +35,10 @@ jobs: if [ "${{ steps.filter.outputs.dependency_injection }}" == "true" ]; then targets+=("DependencyInjection") fi + + if [ "${{ steps.filter.outputs.design_system }}" == "true" ]; then + targets+=("DesignSystem") + fi if [ ${#targets[@]} -gt 0 ]; then matrix="{\"target\": [$(printf '"%s",' "${targets[@]}" | sed 's/,$//')]}" diff --git a/Projects/DesignSystem/Project.swift b/Projects/DesignSystem/Project.swift new file mode 100644 index 0000000..506b511 --- /dev/null +++ b/Projects/DesignSystem/Project.swift @@ -0,0 +1,15 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let moduleName = "DesignSystem" + +let dependecies: [TargetDependency] = [] + +let testDependencies: [TargetDependency] = [ + .external(name: "SnapshotTesting") +] + +let project = Project.templateModule(named: moduleName, + targets: [.source, .test], + dependencies: dependecies, + testDependencies: testDependencies) diff --git a/Projects/DesignSystem/Sources/Components/ErrorView.swift b/Projects/DesignSystem/Sources/Components/ErrorView.swift new file mode 100644 index 0000000..ab2505f --- /dev/null +++ b/Projects/DesignSystem/Sources/Components/ErrorView.swift @@ -0,0 +1,144 @@ +import UIKit + +public final class ErrorView: UIView { + private lazy var iconImageView: UIImageView = { + let config = UIImage.SymbolConfiguration(pointSize: 80, weight: .regular) + let image = UIImage(systemName: "exclamationmark.triangle.fill", + withConfiguration: config) + let imageView = UIImageView(image: image) + imageView.tintColor = .orange + imageView.contentMode = .scaleAspectFit + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .title2) + label.textColor = .label + label.textAlignment = .center + label.numberOfLines = 1 + return label + }() + + private lazy var messageLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .callout) + label.textColor = .secondaryLabel + label.textAlignment = .center + label.numberOfLines = 0 + return label + }() + + private lazy var codeLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .footnote) + label.textColor = .tertiaryLabel + label.textAlignment = .right + label.numberOfLines = 1 + label.isHidden = true + return label + }() + + private lazy var retryButton: UIButton = { + let button = UIButton(type: .system) + let image = UIImage(systemName: "arrow.clockwise") + button.setImage(image, for: .normal) + button.setTitle("Try again", for: .normal) + button.titleLabel?.font = .preferredFont(forTextStyle: .body) + button.tintColor = .systemBlue + button.backgroundColor = .systemBlue.withAlphaComponent(0.15) + button.layer.cornerRadius = DSSpacings.medium.rawValue + button.contentEdgeInsets = UIEdgeInsets( + top: DSSpacings.medium.rawValue, + left: DSSpacings.xLarge.rawValue, + bottom: DSSpacings.medium.rawValue, + right: DSSpacings.xLarge.rawValue + ) + button.imageEdgeInsets = UIEdgeInsets(top: 0, + left: -DSSpacings.small.rawValue, + bottom: 0, + right: DSSpacings.small.rawValue) + button.addTarget(self, action: #selector(retryButtonTapped), for: .touchUpInside) + return button + }() + + private lazy var textStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [titleLabel, messageLabel, codeLabel]) + stackView.axis = .vertical + stackView.alignment = .fill + stackView.spacing = DSSpacings.medium.rawValue + return stackView + }() + + private lazy var mainStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [iconImageView, textStackView, retryButton]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.spacing = DSSpacings.xLarge.rawValue + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + public var retryAction: (() -> Void)? + + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func configure(title: String, + message: String, + code: String? = nil, + buttonText: String? = nil) { + titleLabel.text = title + messageLabel.text = message + + if let code { + codeLabel.text = "code: \(code)" + codeLabel.isHidden = false + } + + if let buttonText { + retryButton.setTitle(buttonText, for: .normal) + } + } + + @objc private func retryButtonTapped() { + retryAction?() + } +} + +extension ErrorView: ViewCode { + public func buildViewHierarch() { + addSubview(mainStackView) + } + + public func setUpConstraints() { + NSLayoutConstraint.activate([ + mainStackView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor), + mainStackView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor), + mainStackView.centerYAnchor.constraint(equalTo: centerYAnchor), + mainStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: DSSpacings.xLarge.rawValue), + mainStackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -DSSpacings.xLarge.rawValue) + ]) + } +} + +#if DEBUG +import SwiftUI + +@available(iOS 17.0, *) +#Preview { + let view = ErrorView() + view.configure(title: "Failed to load Exchanges", + message: "Our server is experiencing problems.\nPlease try again.", + code: "500") + return view +} +#endif diff --git a/Projects/DesignSystem/Sources/Constants/Spacings.swift b/Projects/DesignSystem/Sources/Constants/Spacings.swift new file mode 100644 index 0000000..8ea89a7 --- /dev/null +++ b/Projects/DesignSystem/Sources/Constants/Spacings.swift @@ -0,0 +1,20 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public enum DSSpacings: CGFloat { + case none = 0 + case xSmall = 2 + case small = 4 + case medium = 8 + case large = 16 + case xLarge = 32 + case xxLarge = 64 + case xxxLarge = 128 +} diff --git a/Projects/DesignSystem/Sources/Protocols/ViewCode.swift b/Projects/DesignSystem/Sources/Protocols/ViewCode.swift new file mode 100644 index 0000000..127def2 --- /dev/null +++ b/Projects/DesignSystem/Sources/Protocols/ViewCode.swift @@ -0,0 +1,28 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +public protocol ViewCode: AnyObject { + func buildViewHierarch() + func setUpConstraints() + func additionalConfiguration() +} + +public extension ViewCode { + func setupView() { + buildViewHierarch() + setUpConstraints() + additionalConfiguration() + } + + func buildViewHierarch() {} + func setUpConstraints() {} + func additionalConfiguration() {} +} diff --git a/Projects/DesignSystem/Tests/Components/ErrorViewSnapshotTest.swift b/Projects/DesignSystem/Tests/Components/ErrorViewSnapshotTest.swift new file mode 100644 index 0000000..b1e158d --- /dev/null +++ b/Projects/DesignSystem/Tests/Components/ErrorViewSnapshotTest.swift @@ -0,0 +1,49 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import SnapshotTesting +import Testing + +@testable import DesignSystem + +@MainActor +@Suite() +struct ErrorViewSnapshotTest { + @Test("GIVEN ErrorView THEN it should configure with default values") + func testConfigureDefaultValues() throws { + let sut = makeSut(title: "Failed to load Exchanges", + message: "Our server is experiencing problems.\nPlease try again.") + + assertSnapshot(of: sut, as: .image) + } + + @Test("GIVEN ErrorView THEN it should configure with code and buttons") + func testConfigureCode() throws { + let sut = makeSut(title: "Failed to load Exchanges", + message: "Our server is experiencing problems.\nPlease try again.", + code: "500") + + assertSnapshot(of: sut, as: .image) + } + + func makeSut(title: String, + message: String, + code: String? = nil, + buttonText: String? = nil) -> ErrorView { + let sut = ErrorView() + sut.frame = CGRect(x: 0, y: 0, width: 402, height: 874) + sut.backgroundColor = .white + sut.configure(title: title, + message: message, + code: code, + buttonText: buttonText) + + return sut + } +} diff --git a/Projects/DesignSystem/Tests/Components/__Snapshots__/ErrorViewSnapshotTest/testConfigureCode.1.png b/Projects/DesignSystem/Tests/Components/__Snapshots__/ErrorViewSnapshotTest/testConfigureCode.1.png new file mode 100644 index 0000000000000000000000000000000000000000..f3aefe0bbc473ef7c523942d4159f107207294b1 GIT binary patch literal 106810 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 SYF8rvBblo<{_FTM}NERgMC%0Sl4 z(O?Fkl7H(GLX+6&B%_oZMnc{XWYFFYMm)mT>boPfA-PxQ}s9vrGS{`f$AuShTo;Ro68K$Z>Genfogx~6KUwaF+A zxas}J*S!Xt3Coj)HCj|zLhkM1>_2f@YTov%{tRVsN46*bZr3bWTD7r-?

P*J#Ox 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 I5$jw354)S7C;$Ke literal 0 HcmV?d00001 diff --git a/Tuist/Package.resolved b/Tuist/Package.resolved index 1c13632..f640ad5 100644 --- a/Tuist/Package.resolved +++ b/Tuist/Package.resolved @@ -1,5 +1,32 @@ { "pins" : [ + { + "identity" : "swift-custom-dump", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-custom-dump", + "state" : { + "revision" : "2a2a938798236b8fa0bc57c453ee9de9f9ec3ab0", + "version" : "1.4.1" + } + }, + { + "identity" : "swift-snapshot-testing", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-snapshot-testing.git", + "state" : { + "revision" : "bf8d8c27f0f0c6d5e77bff0db76ab68f2050d15d", + "version" : "1.18.9" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-syntax", + "state" : { + "revision" : "4799286537280063c85a32f09884cfbca301b1a1", + "version" : "602.0.0" + } + }, { "identity" : "swinject", "kind" : "remoteSourceControl", @@ -8,6 +35,15 @@ "revision" : "b685b549fe4d8ae265fc7a2f27d0789720425d69", "version" : "2.10.0" } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "34e463e98ab8541c604af706c99bed7160f5ec70", + "version" : "1.8.1" + } } ], "version" : 2 diff --git a/Tuist/Package.swift b/Tuist/Package.swift index 593d390..9ca806e 100644 --- a/Tuist/Package.swift +++ b/Tuist/Package.swift @@ -13,5 +13,6 @@ let package = Package( name: "ExchangesApp", dependencies: [ .package(url: "https://github.com/Swinject/Swinject.git", from: "2.9.1"), + .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.18.9") ] -) \ No newline at end of file +) diff --git a/Workspace.swift b/Workspace.swift index b9c48c6..24febbc 100644 --- a/Workspace.swift +++ b/Workspace.swift @@ -5,7 +5,8 @@ let workspace = Workspace( name: "ExchangesApp", projects: [ "./Projects/App", - "./Projects/DependencyInjection" + "./Projects/DependencyInjection", + "./Projects/DesignSystem" ], schemes: [], generationOptions: .options(autogeneratedWorkspaceSchemes: .disabled) From 0d88cb21858a4809d3857fad38023869786f4c2a Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:00:18 -0300 Subject: [PATCH 08/16] feat: home module star and navigation (#23) --- .github/workflows/pr_status.yml | 6 ++ Projects/App/Project.swift | 20 ++++- .../App/Sources/Application/AppDelegate.swift | 5 +- .../Sources/Application/SceneDelegate.swift | 30 +++++--- .../Assemblies/CoordinatorAssembly.swift | 35 +++++++++ .../Assemblies/NetworkAssembly.swift.swift | 27 +++++++ .../Sources/Coordinator/AppCoordinator.swift | 35 +++++++++ Projects/App/Sources/ViewController.swift | 16 ---- .../Tests/Application/AppDelegateTests.swift | 56 +++++++++++++- .../Coordinator/AppCoordinatorTests.swift | 50 ++++++++++++ Projects/DependencyInjection/Project.swift | 2 +- .../Testing/DependencyInjectorSpy.swift | 76 +++++++++++++++++++ .../Home/Interfaces/HomeCoordinating.swift | 12 +++ Projects/Home/Project.swift | 22 ++++++ .../Sources/Coordinator/HomeCoordinator.swift | 27 +++++++ .../Coordinator/HomeCoordinatingSpy.swift | 34 +++++++++ Projects/Home/Tests/TestPlaceHolder.swift | 0 .../Navigation/Interfaces/Coordinator.swift | 18 +++++ Projects/Navigation/Project.swift | 10 +++ .../Navigation/Testing/CoordinatorSpy.swift | 33 ++++++++ Tuist/Package.resolved | 9 +++ Tuist/Package.swift | 3 +- .../Project+Template.swift | 6 +- Workspace.swift | 3 +- 24 files changed, 498 insertions(+), 37 deletions(-) create mode 100644 Projects/App/Sources/Assemblies/CoordinatorAssembly.swift create mode 100644 Projects/App/Sources/Assemblies/NetworkAssembly.swift.swift create mode 100644 Projects/App/Sources/Coordinator/AppCoordinator.swift delete mode 100644 Projects/App/Sources/ViewController.swift create mode 100644 Projects/App/Tests/Coordinator/AppCoordinatorTests.swift create mode 100644 Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift create mode 100644 Projects/Home/Interfaces/HomeCoordinating.swift create mode 100644 Projects/Home/Project.swift create mode 100644 Projects/Home/Sources/Coordinator/HomeCoordinator.swift create mode 100644 Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift create mode 100644 Projects/Home/Tests/TestPlaceHolder.swift create mode 100644 Projects/Navigation/Interfaces/Coordinator.swift create mode 100644 Projects/Navigation/Project.swift create mode 100644 Projects/Navigation/Testing/CoordinatorSpy.swift diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index 15bf55b..20bcb29 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -24,6 +24,8 @@ jobs: - 'Projects/DependencyInjection/**' design_system: - 'Projects/DesignSystem/**' + home: + - 'Projects/Home/**' - name: Generate matrix id: matrix run: | @@ -39,6 +41,10 @@ jobs: if [ "${{ steps.filter.outputs.design_system }}" == "true" ]; then targets+=("DesignSystem") fi + + if [ "${{ steps.filter.outputs.home }}" == "true" ]; then + targets+=("Home") + fi if [ ${#targets[@]} -gt 0 ]; then matrix="{\"target\": [$(printf '"%s",' "${targets[@]}" | sed 's/,$//')]}" diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index 75fc026..bde3044 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -7,11 +7,25 @@ let dependecies: [TargetDependency] = [ .project(target: "DependencyInjection", path: "../DependencyInjection"), .project(target: "DependencyInjectionInterfaces", - path: "../DependencyInjection") + path: "../DependencyInjection"), + .project(target: "Home", + path: "../Home"), + .project(target: "HomeInterfaces", + path: "../Home"), + .project(target: "NavigationInterfaces", + path: "../Navigation"), + .external(name: "Networking"), + .external(name: "NetworkingInterfaces"), ] let testDependencies: [TargetDependency] = [ .target(name: moduleName), + .project(target: "DependencyInjectionTesting", + path: "../DependencyInjection"), + .project(target: "HomeTesting", + path: "../Home"), + .project(target: "NavigationTesting", + path: "../Navigation"), ] let project = Project( @@ -59,8 +73,8 @@ let project = Project( "\(moduleName)Tests", // Disabled UITests for now, as they are not yet implemented // "\(moduleName)UITests" - ] - ), + ], + arguments: .arguments(environmentVariables: ["IS_TESTING": "true"])), runAction: .runAction(configuration: .debug, executable: .project(path: ".", target: moduleName), arguments: .arguments(environmentVariables: developmentEnv))) diff --git a/Projects/App/Sources/Application/AppDelegate.swift b/Projects/App/Sources/Application/AppDelegate.swift index 2f123d2..70912bf 100644 --- a/Projects/App/Sources/Application/AppDelegate.swift +++ b/Projects/App/Sources/Application/AppDelegate.swift @@ -32,8 +32,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {} @MainActor - private func setupDependencies() { + func setupDependencies() { let injector = Injector() SharedContainer.shared.setInjector(injector) + + NetworkAssembly(injector: injector).register() + CoordinatorAssembly(injector: injector).register() } } diff --git a/Projects/App/Sources/Application/SceneDelegate.swift b/Projects/App/Sources/Application/SceneDelegate.swift index 18a4ed2..532eb1c 100644 --- a/Projects/App/Sources/Application/SceneDelegate.swift +++ b/Projects/App/Sources/Application/SceneDelegate.swift @@ -6,30 +6,38 @@ // import UIKit +import DependencyInjectionInterfaces class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? + var appCoordinator: AppCoordinating? + + #if DEBUG + var isTesting: Bool { + return ProcessInfo.processInfo.environment["IS_TESTING"] == "true" + } + #endif func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } + #if DEBUG + if isTesting { return } + #endif + let window = UIWindow(windowScene: windowScene) - let nav = UINavigationController(rootViewController: ViewController()) + let nav = UINavigationController() + let resolver = SharedContainer.shared.resolver() + + appCoordinator = resolver.resolve(AppCoordinating.self, argument: nav) + appCoordinator?.start() + window.rootViewController = nav window.makeKeyAndVisible() + self.window = window } - - func sceneDidDisconnect(_ scene: UIScene) {} - - func sceneDidBecomeActive(_ scene: UIScene) {} - - func sceneWillResignActive(_ scene: UIScene) {} - - func sceneWillEnterForeground(_ scene: UIScene) {} - - func sceneDidEnterBackground(_ scene: UIScene) {} } diff --git a/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift b/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift new file mode 100644 index 0000000..6294188 --- /dev/null +++ b/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift @@ -0,0 +1,35 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// +import DependencyInjectionInterfaces +import HomeInterfaces +import Home +import NavigationInterfaces + +import UIKit + +public struct CoordinatorAssembly { + private let injector: DependencyInjector + + public init(injector: DependencyInjector) { + self.injector = injector + } + + @MainActor + public func register() { + injector.register(AppCoordinating.self) { (_, arg: UINavigationController) in + AppCoordinator(navigationController: arg) + } + + injector.register(HomeCoordinating.self) { (_, arg: (UINavigationController, Coordinator?)) in + let (navigationController, parentCoordinator) = arg + + return HomeCoordinator(parentCoordinator: parentCoordinator, + navigationController: navigationController) + } + } +} diff --git a/Projects/App/Sources/Assemblies/NetworkAssembly.swift.swift b/Projects/App/Sources/Assemblies/NetworkAssembly.swift.swift new file mode 100644 index 0000000..8c5ca5f --- /dev/null +++ b/Projects/App/Sources/Assemblies/NetworkAssembly.swift.swift @@ -0,0 +1,27 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import DependencyInjectionInterfaces +import NetworkingInterfaces +import Networking + +import Foundation + +public struct NetworkAssembly { + private let injector: DependencyInjector + + public init(injector: DependencyInjector) { + self.injector = injector + } + + public func register() { + injector.register(NetworkServiceProtocol.self) { _ in + NetworkService() + } + } +} diff --git a/Projects/App/Sources/Coordinator/AppCoordinator.swift b/Projects/App/Sources/Coordinator/AppCoordinator.swift new file mode 100644 index 0000000..124ee30 --- /dev/null +++ b/Projects/App/Sources/Coordinator/AppCoordinator.swift @@ -0,0 +1,35 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import DependencyInjectionInterfaces +import HomeInterfaces +import NavigationInterfaces +import UIKit + +protocol AppCoordinating: Coordinator {} + +@MainActor +final class AppCoordinator: AppCoordinating { + var parentCoordinator: Coordinator? + var children: [Coordinator] = [] + var navigationController: UINavigationController + + init(navigationController: UINavigationController) { + self.navigationController = navigationController + } + + func start() { + let resolver = SharedContainer.shared.resolver() + let arg: (UINavigationController, Coordinator?) = (navigationController, self) + + let homeCoordinator = resolver.resolve(HomeCoordinating.self, + argument: arg) + + homeCoordinator.start() + } +} diff --git a/Projects/App/Sources/ViewController.swift b/Projects/App/Sources/ViewController.swift deleted file mode 100644 index 8ee1793..0000000 --- a/Projects/App/Sources/ViewController.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// ViewController.swift -// ExchangesApp -// -// Created by Vitor Conceicao on 06/02/26. -// - -import UIKit - -class ViewController: UIViewController { - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - view.backgroundColor = .blue - } -} diff --git a/Projects/App/Tests/Application/AppDelegateTests.swift b/Projects/App/Tests/Application/AppDelegateTests.swift index bb6a59e..9f7cd17 100644 --- a/Projects/App/Tests/Application/AppDelegateTests.swift +++ b/Projects/App/Tests/Application/AppDelegateTests.swift @@ -8,15 +8,69 @@ import Testing import DependencyInjectionInterfaces +import NetworkingInterfaces +import HomeInterfaces +import NavigationInterfaces +import UIKit + @testable import App @Suite @MainActor struct AppDelegateTests { + init() { + _ = AppDelegate() + } + @Test("GIVEN AppDelegate initialize THEN it should set injector") - func example() async throws { + func setInjectot() async throws { #expect(throws: Never.self) { _ = SharedContainer.shared.resolver() } } + + @Test("GIVEN AppDelegate initialize THEN it SHOULD register DI Network") + func networkRegister() async throws { + #expect(throws: Never.self) { + let _: NetworkServiceProtocol = SharedContainer.shared.resolver().resolve() + } + } + + @Test("GIVEN AppDelegate initialize THEN it SHOULD register DI Network") + func appCoordinatorRegister() async throws { + #expect(throws: Never.self) { + let navigation = UINavigationController() + _ = SharedContainer + .shared + .resolver() + .resolve(AppCoordinating.self, argument: navigation) + } + } + + @Test("GIVEN AppDelegate initialize THEN it SHOULD register DI AppCoordinating") + func appCoordinatingRegister() async throws { + #expect(throws: Never.self) { + let navigation = UINavigationController() + _ = SharedContainer + .shared + .resolver() + .resolve(AppCoordinating.self, argument: navigation) + } + } + + @Test("GIVEN AppDelegate initialize THEN it SHOULD register DI HomeCoordinating") + func homeCoordinatorRegister() async throws { + #expect(throws: Never.self) { + let navigation = UINavigationController() + let parentCoordinator: Coordinator? = SharedContainer + .shared + .resolver() + .resolve(AppCoordinating.self, argument: navigation) + + _ = SharedContainer + .shared + .resolver() + .resolve(HomeCoordinating.self, argument: (navigation, parentCoordinator)) + } + } } diff --git a/Projects/App/Tests/Coordinator/AppCoordinatorTests.swift b/Projects/App/Tests/Coordinator/AppCoordinatorTests.swift new file mode 100644 index 0000000..eaa720a --- /dev/null +++ b/Projects/App/Tests/Coordinator/AppCoordinatorTests.swift @@ -0,0 +1,50 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// +// +import DependencyInjectionInterfaces +import DependencyInjectionTesting +import HomeInterfaces +import HomeTesting +import NavigationInterfaces +import NavigationTesting +import Testing +import UIKit + +@testable import App + +@MainActor +@Suite("AppCoordinator Tests") +struct AppCoordinatorTests { + + // MARK: - Start Tests + + @Test("Start resolves HomeCoordinating from container") + func startResolvesHomeCoordinator() { + // Given + let navigationController = UINavigationController() + let sut = AppCoordinator(navigationController: navigationController) + + let injectorSpy = DependencyInjectorSpy() + let homeCoordinatorSpy = HomeCoordinatingSpy( + children: [], + navigationController: navigationController + ) + + injectorSpy + .register(HomeCoordinating.self) { (_, arg: (UINavigationController, Coordinator?)) in + homeCoordinatorSpy + } + + SharedContainer.shared.setInjector(injectorSpy) + + sut.start() + + #expect(injectorSpy.calledMethods.contains(.resolveWithArgument)) + #expect(homeCoordinatorSpy.calledMethods.contains(.start)) + } +} diff --git a/Projects/DependencyInjection/Project.swift b/Projects/DependencyInjection/Project.swift index 134e69f..e4eb0aa 100644 --- a/Projects/DependencyInjection/Project.swift +++ b/Projects/DependencyInjection/Project.swift @@ -8,5 +8,5 @@ let dependecies: [TargetDependency] = [ ] let project = Project.templateModule(named: moduleName, - targets: [.source,. interfaces, .test], + targets: [.source,. interfaces, .test, .testing], dependencies: dependecies) diff --git a/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift b/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift new file mode 100644 index 0000000..fb1510c --- /dev/null +++ b/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift @@ -0,0 +1,76 @@ +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import DependencyInjectionInterfaces +import Foundation + +public final class DependencyInjectorSpy: DependencyInjector { + public init() {} + + public enum Method { + case register + case registerWithArgument + case resolve + case resolveWithArgument + } + + // Container to hold registered services and their factories + private var registeredServices: [String: Any] = [:] + private var registeredServicesWithArgument: [String: Any] = [:] + + public var calledMethods: [Method] = [] + + private func typeIdentifier(_ type: T.Type) -> String { + return String(reflecting: type) + } + + public func register(_ serviceType: Service.Type, + factory: @escaping (DependencyResolver) -> Service) { + calledMethods.append(.register) + let identifier = typeIdentifier(serviceType) + registeredServices[identifier] = factory + } + + public func register(_ serviceType: Service.Type, + factory: @escaping (DependencyResolver, Argument) -> Service) { + calledMethods.append(.registerWithArgument) + let identifier = typeIdentifier(serviceType) + registeredServicesWithArgument[identifier] = factory + } + + public func resolve() -> Service { + calledMethods.append(.resolve) + let identifier = typeIdentifier(Service.self) + + if let factory = registeredServices[identifier] as? (DependencyResolver) -> Service { + return factory(self) + } + + fatalError("No mock or registration found for \(identifier). Use stub(for:mock:) to configure a mock.") + } + + public func resolve(_ serviceType: Service.Type, + argument: Argument) -> Service { + calledMethods.append(.resolveWithArgument) + let identifier = typeIdentifier(serviceType) + + if let factory = registeredServicesWithArgument[identifier] as? (DependencyResolver, Argument) -> Service { + return factory(self, argument) + } + + fatalError("No mock or registration found for \(identifier). Use stub(for:mock:) to configure a mock.") + } + + // MARK: - Test Helpers + + /// Clear all registrations and mocks + public func reset() { + registeredServices.removeAll() + registeredServicesWithArgument.removeAll() + calledMethods.removeAll() + } +} diff --git a/Projects/Home/Interfaces/HomeCoordinating.swift b/Projects/Home/Interfaces/HomeCoordinating.swift new file mode 100644 index 0000000..651ad83 --- /dev/null +++ b/Projects/Home/Interfaces/HomeCoordinating.swift @@ -0,0 +1,12 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import NavigationInterfaces +import UIKit + +public protocol HomeCoordinating: Coordinator {} diff --git a/Projects/Home/Project.swift b/Projects/Home/Project.swift new file mode 100644 index 0000000..b1e2751 --- /dev/null +++ b/Projects/Home/Project.swift @@ -0,0 +1,22 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let moduleName = "Home" + +let dependecies: [TargetDependency] = [ + .project(target: "DependencyInjectionInterfaces", + path: "../DependencyInjection"), + .project(target: "DesignSystem", + path: "../DesignSystem"), + .external(name: "NetworkingInterfaces"), +] + +let interfaceDependecies: [TargetDependency] = [ + .project(target: "NavigationInterfaces", + path: "../Navigation"), +] + +let project = Project.templateModule(named: moduleName, + targets: [.source,. interfaces, .test, .testing], + dependencies: dependecies, + interfaceDependecies: interfaceDependecies) diff --git a/Projects/Home/Sources/Coordinator/HomeCoordinator.swift b/Projects/Home/Sources/Coordinator/HomeCoordinator.swift new file mode 100644 index 0000000..718b789 --- /dev/null +++ b/Projects/Home/Sources/Coordinator/HomeCoordinator.swift @@ -0,0 +1,27 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import HomeInterfaces +import NavigationInterfaces +import UIKit + +public final class HomeCoordinator: HomeCoordinating { + public var parentCoordinator: (Coordinator)? + public var children: [Coordinator] = [] + public var navigationController: UINavigationController + + public init(parentCoordinator: Coordinator? = nil, + navigationController: UINavigationController) { + self.parentCoordinator = parentCoordinator + self.navigationController = navigationController + } + + public func start() { + + } +} diff --git a/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift b/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift new file mode 100644 index 0000000..218d4cf --- /dev/null +++ b/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift @@ -0,0 +1,34 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import HomeInterfaces +import NavigationInterfaces +import UIKit + +public final class HomeCoordinatingSpy: HomeCoordinating { + public enum Method { + case start + } + + public var calledMethods: [Method] = [] + public var parentCoordinator: Coordinator? + public var children: [Coordinator] = [] + public var navigationController: UINavigationController + + public init(parentCoordinator: Coordinator? = nil, + children: [Coordinator], + navigationController: UINavigationController) { + self.parentCoordinator = parentCoordinator + self.children = children + self.navigationController = navigationController + } + + public func start() { + calledMethods.append(.start) + } +} diff --git a/Projects/Home/Tests/TestPlaceHolder.swift b/Projects/Home/Tests/TestPlaceHolder.swift new file mode 100644 index 0000000..e69de29 diff --git a/Projects/Navigation/Interfaces/Coordinator.swift b/Projects/Navigation/Interfaces/Coordinator.swift new file mode 100644 index 0000000..27cfa90 --- /dev/null +++ b/Projects/Navigation/Interfaces/Coordinator.swift @@ -0,0 +1,18 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit + +@MainActor +public protocol Coordinator: AnyObject { + var parentCoordinator: Coordinator? { get set } + var children: [Coordinator] { get set } + var navigationController: UINavigationController { get set } + + func start() +} diff --git a/Projects/Navigation/Project.swift b/Projects/Navigation/Project.swift new file mode 100644 index 0000000..e594ae8 --- /dev/null +++ b/Projects/Navigation/Project.swift @@ -0,0 +1,10 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let moduleName = "Navigation" + +let dependecies: [TargetDependency] = [] + +let project = Project.templateModule(named: moduleName, + targets: [.interfaces, .testing], + dependencies: dependecies) diff --git a/Projects/Navigation/Testing/CoordinatorSpy.swift b/Projects/Navigation/Testing/CoordinatorSpy.swift new file mode 100644 index 0000000..2c0ee6f --- /dev/null +++ b/Projects/Navigation/Testing/CoordinatorSpy.swift @@ -0,0 +1,33 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import NavigationInterfaces +import UIKit + +public final class CoordinatorSpy: Coordinator { + public enum Method { + case start + } + + public var calledMethods: [Method] = [] + public var parentCoordinator: Coordinator? + public var children: [Coordinator] = [] + public var navigationController: UINavigationController + + public init(parentCoordinator: Coordinator? = nil, + children: [Coordinator], + navigationController: UINavigationController) { + self.parentCoordinator = parentCoordinator + self.children = children + self.navigationController = navigationController + } + + public func start() { + calledMethods.append(.start) + } +} diff --git a/Tuist/Package.resolved b/Tuist/Package.resolved index f640ad5..3cbbe40 100644 --- a/Tuist/Package.resolved +++ b/Tuist/Package.resolved @@ -1,5 +1,14 @@ { "pins" : [ + { + "identity" : "networking-package", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vitor-rc1/networking-package.git", + "state" : { + "revision" : "b5498ee2ab408592d4db9a9c95faec3a08de9ea2", + "version" : "1.1.0" + } + }, { "identity" : "swift-custom-dump", "kind" : "remoteSourceControl", diff --git a/Tuist/Package.swift b/Tuist/Package.swift index 9ca806e..f545677 100644 --- a/Tuist/Package.swift +++ b/Tuist/Package.swift @@ -13,6 +13,7 @@ let package = Package( name: "ExchangesApp", dependencies: [ .package(url: "https://github.com/Swinject/Swinject.git", from: "2.9.1"), - .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.18.9") + .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.18.9"), + .package(url: "https://github.com/vitor-rc1/networking-package.git", from: "1.1.0") ] ) diff --git a/Tuist/ProjectDescriptionHelpers/Project+Template.swift b/Tuist/ProjectDescriptionHelpers/Project+Template.swift index 241da1b..996e655 100644 --- a/Tuist/ProjectDescriptionHelpers/Project+Template.swift +++ b/Tuist/ProjectDescriptionHelpers/Project+Template.swift @@ -10,7 +10,7 @@ public let developmentEnv: [String: EnvironmentVariable] = [ "CM_API_BASE_URL": cmApiBaseURL, ] -public let iOSDeploymentTarget: DeploymentTargets = .iOS("14.0") +public let iOSDeploymentTarget: DeploymentTargets = .iOS("15.0") public let commonSettings: SettingsDictionary = [ "SWIFT_VERSION": "6.0" ] @@ -24,6 +24,7 @@ public extension Project { targets: [ModuleTargets] = [.source, .interfaces, .test], dependencies: [TargetDependency] = [], testDependencies: [TargetDependency] = [], + interfaceDependecies: [TargetDependency] = [], shouldSetEnvVars: Bool = false) -> Project { var selectedTargets: [Target] = [] @@ -38,7 +39,8 @@ public extension Project { buildableFolders: ["Interfaces"], scripts: [ swiftLintScript - ]) + ], + dependencies: interfaceDependecies) ) } diff --git a/Workspace.swift b/Workspace.swift index 24febbc..de4324c 100644 --- a/Workspace.swift +++ b/Workspace.swift @@ -6,7 +6,8 @@ let workspace = Workspace( projects: [ "./Projects/App", "./Projects/DependencyInjection", - "./Projects/DesignSystem" + "./Projects/DesignSystem", + "./Projects/Home" ], schemes: [], generationOptions: .options(autogeneratedWorkspaceSchemes: .disabled) From 18dec3476250d63859f22607fa3a50e3a35ade7d Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Mon, 9 Feb 2026 07:43:59 -0300 Subject: [PATCH 09/16] feat: home scene (#24) --- .../Base.lproj/LaunchScreen.storyboard | 30 ++- .../Sources/Coordinator/HomeCoordinator.swift | 14 +- Projects/Home/Sources/Model/Exchange.swift | 61 ++++++ .../Home/Sources/Model/ExchangeDetail.swift | 35 ++++ .../Model/ExchangeDetailResponse.swift | 14 ++ .../Home/Sources/Model/ExchangeResponse.swift | 14 ++ .../Home/Sources/Model/ExchangeSummary.swift | 14 ++ .../Home/Sources/Model/ExchangeUrls.swift | 14 ++ .../Home/Sources/Model/HomeViewState.swift | 17 ++ Projects/Home/Sources/Model/Status.swift | 27 +++ .../Protocols/HomeServiceProtocol.swift | 14 ++ .../HomeViewModelCoordinatorDelegate.swift | 14 ++ .../Protocols/HomeViewModelDelegate.swift | 14 ++ .../Protocols/HomeViewModelProtocol.swift | 19 ++ .../Home/Sources/Service/HomeEndpoint.swift | 40 ++++ .../Home/Sources/Service/HomeService.swift | 54 +++++ .../Sources/View/HomeViewController.swift | 162 +++++++++++++++ .../Sources/ViewModel/HomeViewModel.swift | 110 +++++++++++ .../Doubles/HomeServiceProtocolSpy.swift | 46 +++++ .../HomeViewModelCoordinatorDelegateSpy.swift | 23 +++ .../Doubles/HomeViewModelDelegateSpy.swift | 23 +++ .../Home/Tests/Doubles/HomeViewModelSpy.swift | 37 ++++ .../Doubles/NetworkServiceProtocolSpy.swift | 29 +++ .../Tests/Service/HomeEndpointTests.swift | 57 ++++++ .../Home/Tests/Service/HomeServiceTests.swift | 185 ++++++++++++++++++ Projects/Home/Tests/TestPlaceHolder.swift | 0 .../Tests/View/HomeViewControllerTests.swift | 91 +++++++++ .../Tests/ViewModel/HomeViewModelTests.swift | 172 ++++++++++++++++ 28 files changed, 1324 insertions(+), 6 deletions(-) create mode 100644 Projects/Home/Sources/Model/Exchange.swift create mode 100644 Projects/Home/Sources/Model/ExchangeDetail.swift create mode 100644 Projects/Home/Sources/Model/ExchangeDetailResponse.swift create mode 100644 Projects/Home/Sources/Model/ExchangeResponse.swift create mode 100644 Projects/Home/Sources/Model/ExchangeSummary.swift create mode 100644 Projects/Home/Sources/Model/ExchangeUrls.swift create mode 100644 Projects/Home/Sources/Model/HomeViewState.swift create mode 100644 Projects/Home/Sources/Model/Status.swift create mode 100644 Projects/Home/Sources/Protocols/HomeServiceProtocol.swift create mode 100644 Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift create mode 100644 Projects/Home/Sources/Protocols/HomeViewModelDelegate.swift create mode 100644 Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift create mode 100644 Projects/Home/Sources/Service/HomeEndpoint.swift create mode 100644 Projects/Home/Sources/Service/HomeService.swift create mode 100644 Projects/Home/Sources/View/HomeViewController.swift create mode 100644 Projects/Home/Sources/ViewModel/HomeViewModel.swift create mode 100644 Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift create mode 100644 Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift create mode 100644 Projects/Home/Tests/Doubles/HomeViewModelDelegateSpy.swift create mode 100644 Projects/Home/Tests/Doubles/HomeViewModelSpy.swift create mode 100644 Projects/Home/Tests/Doubles/NetworkServiceProtocolSpy.swift create mode 100644 Projects/Home/Tests/Service/HomeEndpointTests.swift create mode 100644 Projects/Home/Tests/Service/HomeServiceTests.swift delete mode 100644 Projects/Home/Tests/TestPlaceHolder.swift create mode 100644 Projects/Home/Tests/View/HomeViewControllerTests.swift create mode 100644 Projects/Home/Tests/ViewModel/HomeViewModelTests.swift diff --git a/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard b/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard index 865e932..fb0e9a4 100644 --- a/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard +++ b/Projects/App/Resources/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ - - + + + - + + + @@ -11,10 +14,22 @@ - + - + + + + + + + + @@ -22,4 +37,9 @@ + + + + + diff --git a/Projects/Home/Sources/Coordinator/HomeCoordinator.swift b/Projects/Home/Sources/Coordinator/HomeCoordinator.swift index 718b789..2206557 100644 --- a/Projects/Home/Sources/Coordinator/HomeCoordinator.swift +++ b/Projects/Home/Sources/Coordinator/HomeCoordinator.swift @@ -6,8 +6,10 @@ // // +import DependencyInjectionInterfaces import HomeInterfaces import NavigationInterfaces +import NetworkingInterfaces import UIKit public final class HomeCoordinator: HomeCoordinating { @@ -22,6 +24,16 @@ public final class HomeCoordinator: HomeCoordinating { } public func start() { - + let resolver = SharedContainer.shared.resolver() + let networkService: NetworkServiceProtocol = resolver.resolve() + let service = HomeService(networkService: networkService) + let viewModel = HomeViewModel(service: service) + viewModel.coordinatorDelegate = self + let homeVC = HomeViewController(viewModel: viewModel) + navigationController.pushViewController(homeVC, animated: false) } } + +extension HomeCoordinator: HomeViewModelCoordinatorDelegate { + func navigateToDetails(of exchange: Exchange) {} +} diff --git a/Projects/Home/Sources/Model/Exchange.swift b/Projects/Home/Sources/Model/Exchange.swift new file mode 100644 index 0000000..bb5e0c9 --- /dev/null +++ b/Projects/Home/Sources/Model/Exchange.swift @@ -0,0 +1,61 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct Exchange: Equatable, Identifiable { + let id: Int + let name: String + let description: String? + let logo: String + let spotVolumeUsd: Double? + let makerFee: Double + let takerFee: Double + let dateLaunched: String + let websiteUrl: String? + let twitterUrl: String? + + let isLoadingDetails: Bool + + init(id: Int, + name: String, + description: String? = nil, + logo: String, + spotVolumeUsd: Double? = nil, + makerFee: Double, + takerFee: Double, + dateLaunched: String, + websiteUrl: String? = nil, + twitterUrl: String? = nil) { + self.id = id + self.name = name + self.description = description + self.logo = logo + self.spotVolumeUsd = spotVolumeUsd + self.makerFee = makerFee + self.takerFee = takerFee + self.dateLaunched = dateLaunched + self.websiteUrl = websiteUrl + self.twitterUrl = twitterUrl + self.isLoadingDetails = false + } + + init(summary: ExchangeSummary) { + self.id = summary.id + self.name = summary.name + self.description = nil + self.logo = "" + self.spotVolumeUsd = nil + self.makerFee = 0.0 + self.takerFee = 0.0 + self.dateLaunched = "" + self.websiteUrl = nil + self.twitterUrl = nil + self.isLoadingDetails = true + } +} diff --git a/Projects/Home/Sources/Model/ExchangeDetail.swift b/Projects/Home/Sources/Model/ExchangeDetail.swift new file mode 100644 index 0000000..ec924e2 --- /dev/null +++ b/Projects/Home/Sources/Model/ExchangeDetail.swift @@ -0,0 +1,35 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct ExchangeDetail: Equatable { + let id: Int + let name: String + let description: String? + let logo: String + let spotVolumeUsd: Double? + let makerFee: Double + let takerFee: Double + let dateLaunched: String + let urls: ExchangeURLs +} + +extension ExchangeDetail: Codable { + enum CodingKeys: String, CodingKey { + case id + case name + case description + case logo + case spotVolumeUsd = "spot_volume_usd" + case makerFee = "maker_fee" + case takerFee = "taker_fee" + case dateLaunched = "date_launched" + case urls + } +} diff --git a/Projects/Home/Sources/Model/ExchangeDetailResponse.swift b/Projects/Home/Sources/Model/ExchangeDetailResponse.swift new file mode 100644 index 0000000..dd4bd38 --- /dev/null +++ b/Projects/Home/Sources/Model/ExchangeDetailResponse.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct ExchangeDetailResponse: Codable { + let status: Status + let data: [String: T] +} diff --git a/Projects/Home/Sources/Model/ExchangeResponse.swift b/Projects/Home/Sources/Model/ExchangeResponse.swift new file mode 100644 index 0000000..318aa80 --- /dev/null +++ b/Projects/Home/Sources/Model/ExchangeResponse.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct ExchangeResponse: Codable { + let status: Status + let data: [T] +} diff --git a/Projects/Home/Sources/Model/ExchangeSummary.swift b/Projects/Home/Sources/Model/ExchangeSummary.swift new file mode 100644 index 0000000..57f83e1 --- /dev/null +++ b/Projects/Home/Sources/Model/ExchangeSummary.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct ExchangeSummary: Equatable, Codable { + let id: Int + let name: String +} diff --git a/Projects/Home/Sources/Model/ExchangeUrls.swift b/Projects/Home/Sources/Model/ExchangeUrls.swift new file mode 100644 index 0000000..cfe17f9 --- /dev/null +++ b/Projects/Home/Sources/Model/ExchangeUrls.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct ExchangeURLs: Equatable, Codable { + let website: [String] + let twitter: [String] +} diff --git a/Projects/Home/Sources/Model/HomeViewState.swift b/Projects/Home/Sources/Model/HomeViewState.swift new file mode 100644 index 0000000..b55f15f --- /dev/null +++ b/Projects/Home/Sources/Model/HomeViewState.swift @@ -0,0 +1,17 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +enum HomeViewState: Equatable { + case loading + case loadingMore + case empty + case loaded + case error(String) +} diff --git a/Projects/Home/Sources/Model/Status.swift b/Projects/Home/Sources/Model/Status.swift new file mode 100644 index 0000000..f848afa --- /dev/null +++ b/Projects/Home/Sources/Model/Status.swift @@ -0,0 +1,27 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct Status: Equatable { + let timestamp: String + let errorCode: Int? + let errorMessage: String? + let elapsed: Int + let creditCount: Int +} + +extension Status: Codable { + enum CodingKeys: String, CodingKey { + case timestamp + case errorCode = "error_code" + case errorMessage = "error_message" + case elapsed + case creditCount = "credit_count" + } +} diff --git a/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift b/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift new file mode 100644 index 0000000..00fbce6 --- /dev/null +++ b/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +protocol HomeServiceProtocol: AnyObject, Sendable { + func fetchExchangesList(page: Int, limit: Int) async throws -> [ExchangeSummary] + func fetchDetailsFor(ids: [String]) async throws -> [ExchangeDetail] +} diff --git a/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift b/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift new file mode 100644 index 0000000..53df5d6 --- /dev/null +++ b/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +protocol HomeViewModelCoordinatorDelegate: AnyObject { + func navigateToDetails(of exchange: Exchange) +} diff --git a/Projects/Home/Sources/Protocols/HomeViewModelDelegate.swift b/Projects/Home/Sources/Protocols/HomeViewModelDelegate.swift new file mode 100644 index 0000000..3a53969 --- /dev/null +++ b/Projects/Home/Sources/Protocols/HomeViewModelDelegate.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +protocol HomeViewModelDelegate: AnyObject { + func didUpdateState(_ state: HomeViewState) +} diff --git a/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift b/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift new file mode 100644 index 0000000..5d6fe8a --- /dev/null +++ b/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift @@ -0,0 +1,19 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +protocol HomeViewModelProtocol: AnyObject { + var delegate: HomeViewModelDelegate? { get set } + var numberOfItems: Int { get } + + func loadData() + func item(at index: Int) -> Exchange + func didSelectRow(at index: Int) +} diff --git a/Projects/Home/Sources/Service/HomeEndpoint.swift b/Projects/Home/Sources/Service/HomeEndpoint.swift new file mode 100644 index 0000000..2f1f0ff --- /dev/null +++ b/Projects/Home/Sources/Service/HomeEndpoint.swift @@ -0,0 +1,40 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import NetworkingInterfaces +import Foundation + +enum HomeEndpoint: APIEndpointProtocol { + case fetchItems(page: Int, limit: Int) + case fetchDetail(ids: [String]) + + var baseURL: String { + ProcessInfo.processInfo.environment["CM_API_BASE_URL"] ?? "" + } + + var path: String { + let basePath: String = "/v1/exchange/" + switch self { + case let .fetchItems(page, limit): + return "\(basePath)map?start=\(page)&limit=\(limit)" + case let .fetchDetail(ids): + let idsQuery = ids.joined(separator: ",") + return "\(basePath)info?id=\(idsQuery)" + } + } + + var method: NetworkingInterfaces.HTTPMethod { + .get + } + + var headers: [String: String]? { + [ + "X-CMC_PRO_API_KEY": ProcessInfo.processInfo.environment["CM_API_KEY"] ?? "" + ] + } +} diff --git a/Projects/Home/Sources/Service/HomeService.swift b/Projects/Home/Sources/Service/HomeService.swift new file mode 100644 index 0000000..b07ed9c --- /dev/null +++ b/Projects/Home/Sources/Service/HomeService.swift @@ -0,0 +1,54 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import NetworkingInterfaces + +enum ServiceError: Error, Equatable { + case decodeFail(String?) + case network(Status) +} + +final class HomeService: Sendable { + private nonisolated(unsafe) let networkService: NetworkServiceProtocol + + init(networkService: NetworkServiceProtocol) { + self.networkService = networkService + } + + private func performRequest(endpoint: APIEndpointProtocol) async throws -> T { + let (data, httpUrlResponse) = try await networkService.request(endpoint: endpoint) + + switch httpUrlResponse.statusCode { + case 200...299: + return try decodeResponse(data) + default: + let error: Status = try decodeResponse(data) + throw ServiceError.network(error) + } + } + + func decodeResponse(_ data: Data) throws -> T { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } +} + +extension HomeService: HomeServiceProtocol { + func fetchExchangesList(page: Int, limit: Int) async throws -> [ExchangeSummary] { + let endpoint = HomeEndpoint.fetchItems(page: page, limit: limit) + let response: ExchangeResponse = try await performRequest(endpoint: endpoint) + return response.data + } + + func fetchDetailsFor(ids: [String]) async throws -> [ExchangeDetail] { + let endpoint = HomeEndpoint.fetchDetail(ids: ids) + let response: ExchangeDetailResponse = try await performRequest(endpoint: endpoint) + return Array(response.data.values) + } +} diff --git a/Projects/Home/Sources/View/HomeViewController.swift b/Projects/Home/Sources/View/HomeViewController.swift new file mode 100644 index 0000000..f7b97d3 --- /dev/null +++ b/Projects/Home/Sources/View/HomeViewController.swift @@ -0,0 +1,162 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit + +class HomeViewController: UIViewController { + + private let viewModel: HomeViewModelProtocol + + private lazy var tableView: UITableView = { + let tableView = UITableView() + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + tableView.isHidden = true + tableView.delegate = self + tableView.dataSource = self + return tableView + }() + + private lazy var loadingIndicator: UIActivityIndicatorView = { + let indicator = UIActivityIndicatorView(style: .large) + indicator.translatesAutoresizingMaskIntoConstraints = false + indicator.hidesWhenStopped = true + return indicator + }() + + private lazy var footerSpinner: UIActivityIndicatorView = { + let spinner = UIActivityIndicatorView(style: .medium) + spinner.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44) + spinner.hidesWhenStopped = true + return spinner + }() + + private lazy var messageLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.textAlignment = .center + label.numberOfLines = 0 + label.isHidden = true + return label + }() + + init(viewModel: HomeViewModelProtocol) { + self.viewModel = viewModel + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { fatalError() } + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .systemBackground + title = "Exchanges" + setupLayout() + + tableView.tableFooterView = footerSpinner + + viewModel.delegate = self + viewModel.loadData() + } + + private func setupLayout() { + view.addSubview(tableView) + view.addSubview(loadingIndicator) + view.addSubview(messageLabel) + + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + + loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), + loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor), + + messageLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), + messageLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor), + messageLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), + messageLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20) + ]) + } +} + +// MARK: - Delegate (Updates) +extension HomeViewController: HomeViewModelDelegate { + func didUpdateState(_ state: HomeViewState) { + switch state { + case .loading: + loadingIndicator.startAnimating() + tableView.isHidden = true + messageLabel.isHidden = true + + case .loadingMore: + footerSpinner.startAnimating() + + case .loaded: + loadingIndicator.stopAnimating() + footerSpinner.stopAnimating() + messageLabel.isHidden = true + tableView.isHidden = false + tableView.reloadData() + + case .empty: + loadingIndicator.stopAnimating() + messageLabel.text = "No exchanges found.." + messageLabel.isHidden = false + + case .error(let msg): + loadingIndicator.stopAnimating() + footerSpinner.stopAnimating() + if viewModel.numberOfItems == 0 { + messageLabel.text = msg + messageLabel.isHidden = false + } else { + print(msg) + } + } + } +} + +// MARK: - TableView (Pagination & Cells) +extension HomeViewController: UITableViewDataSource, UITableViewDelegate { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return viewModel.numberOfItems + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) + let item = viewModel.item(at: indexPath.row) + + var content = cell.defaultContentConfiguration() + content.text = item.name + + if item.isLoadingDetails { + content.secondaryText = "Loading..." + content.secondaryTextProperties.color = .systemBlue + } else { + content.secondaryText = "See more" + content.secondaryTextProperties.color = .secondaryLabel + } + + cell.contentConfiguration = content + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + viewModel.didSelectRow(at: indexPath.row) + } + + func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + let threshold = viewModel.numberOfItems - 3 + if indexPath.row >= threshold { + viewModel.loadData() + } + } +} diff --git a/Projects/Home/Sources/ViewModel/HomeViewModel.swift b/Projects/Home/Sources/ViewModel/HomeViewModel.swift new file mode 100644 index 0000000..c237f41 --- /dev/null +++ b/Projects/Home/Sources/ViewModel/HomeViewModel.swift @@ -0,0 +1,110 @@ +import Foundation + +@MainActor +final class HomeViewModel: HomeViewModelProtocol { + weak var delegate: HomeViewModelDelegate? + weak var coordinatorDelegate: HomeViewModelCoordinatorDelegate? + + private let service: HomeServiceProtocol + + private var currentPage = 1 + private var isFetching = false + private var hasMorePages = true + + private(set) var exchanges: [Exchange] = [] + private(set) var state: HomeViewState = .loading { + didSet { delegate?.didUpdateState(state) } + } + + var numberOfItems: Int { exchanges.count } + + init(service: HomeServiceProtocol) { + self.service = service + } + + func loadData() { + guard !isFetching && hasMorePages else { return } + + isFetching = true + + if exchanges.isEmpty { + state = .loading + } else { + state = .loadingMore + } + + Task { + do { + let summaries = try await service.fetchExchangesList(page: currentPage, limit: 20) + + if summaries.isEmpty { + hasMorePages = false + isFetching = false + if exchanges.isEmpty { + state = .empty + } else { + state = .loaded + } + return + } + + let newItems = summaries.map { Exchange(summary: $0) } + self.exchanges.append(contentsOf: newItems) + + state = .loaded + + let ids = summaries.map { "\($0.id)" } + guard !ids.isEmpty else { + hasMorePages = false + isFetching = false + return + } + + let detailsList = try await service.fetchDetailsFor(ids: ids) + + let detailsMap = Dictionary(uniqueKeysWithValues: detailsList.map { ($0.id, $0) }) + + self.exchanges = self.exchanges.map { item in + guard let detail = detailsMap[item.id] else { return item } + + return mapToExchange(item, detail) + } + + currentPage += 1 + isFetching = false + state = .loaded + + } catch { + isFetching = false + if exchanges.isEmpty { + state = .error(error.localizedDescription) + } else { + print("Fail to load page: \(error)") + state = .loaded + } + } + } + } + + func item(at index: Int) -> Exchange { + exchanges[index] + } + + func didSelectRow(at index: Int) { + guard exchanges.indices.contains(index) else { return } + coordinatorDelegate?.navigateToDetails(of: exchanges[index]) + } + + private func mapToExchange(_ item: Exchange, _ detail: ExchangeDetail) -> Exchange { + return Exchange(id: item.id, + name: item.name, + description: detail.description, + logo: detail.logo, + spotVolumeUsd: detail.spotVolumeUsd, + makerFee: detail.makerFee, + takerFee: detail.takerFee, + dateLaunched: detail.dateLaunched, + websiteUrl: detail.urls.website.first, + twitterUrl: detail.urls.twitter.first) + } +} diff --git a/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift b/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift new file mode 100644 index 0000000..c801368 --- /dev/null +++ b/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift @@ -0,0 +1,46 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Home + +@MainActor +final class HomeServiceProtocolSpy: HomeServiceProtocol, Sendable { + enum Method: Equatable { + case fetchExchangesList + case fetchDetailsFor + } + + var calledMethods: [Method] = [] + var fetchExchangesListResult: Result<[ExchangeSummary], Error>? + var fetchDetailsForResult: Result<[ExchangeDetail], Error>? + + func fetchExchangesList(page: Int, limit: Int) async throws -> [ExchangeSummary] { + await MainActor.run { + calledMethods.append(.fetchExchangesList) + } + + guard let result = fetchExchangesListResult else { + fatalError("fetchExchangesListResult not set") + } + + return try result.get() + } + + func fetchDetailsFor(ids: [String]) async throws -> [ExchangeDetail] { + await MainActor.run { + calledMethods.append(.fetchDetailsFor) + } + + guard let result = fetchDetailsForResult else { + fatalError("fetchDetailsForResult not set") + } + + return try result.get() + } +} diff --git a/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift b/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift new file mode 100644 index 0000000..8ca5226 --- /dev/null +++ b/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift @@ -0,0 +1,23 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Home + +@MainActor +final class HomeViewModelCoordinatorDelegateSpy: HomeViewModelCoordinatorDelegate { + enum Method: Equatable { + case navigateToDetails(Exchange) + } + + var calledMethods: [Method] = [] + + func navigateToDetails(of exchange: Exchange) { + calledMethods.append(.navigateToDetails(exchange)) + } +} diff --git a/Projects/Home/Tests/Doubles/HomeViewModelDelegateSpy.swift b/Projects/Home/Tests/Doubles/HomeViewModelDelegateSpy.swift new file mode 100644 index 0000000..d04ce3c --- /dev/null +++ b/Projects/Home/Tests/Doubles/HomeViewModelDelegateSpy.swift @@ -0,0 +1,23 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Home + +@MainActor +final class HomeViewModelDelegateSpy: HomeViewModelDelegate { + enum Method: Equatable { + case didUpdateState(HomeViewState) + } + + var calledMethods: [Method] = [] + + func didUpdateState(_ state: HomeViewState) { + calledMethods.append(.didUpdateState(state)) + } +} diff --git a/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift b/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift new file mode 100644 index 0000000..28f4feb --- /dev/null +++ b/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift @@ -0,0 +1,37 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Home + +@MainActor +final class HomeViewModelSpy: HomeViewModelProtocol { + enum Method: Equatable { + case loadData + case item + case didSelectRow + } + + var calledMethods: [Method] = [] + var delegate: HomeViewModelDelegate? + var numberOfItems: Int = 0 + var itemsToReturn: [Exchange] = [] + + func loadData() { + calledMethods.append(.loadData) + } + + func item(at index: Int) -> Exchange { + calledMethods.append(.item) + return itemsToReturn[index] + } + + func didSelectRow(at index: Int) { + calledMethods.append(.didSelectRow) + } +} diff --git a/Projects/Home/Tests/Doubles/NetworkServiceProtocolSpy.swift b/Projects/Home/Tests/Doubles/NetworkServiceProtocolSpy.swift new file mode 100644 index 0000000..da4fd58 --- /dev/null +++ b/Projects/Home/Tests/Doubles/NetworkServiceProtocolSpy.swift @@ -0,0 +1,29 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import NetworkingInterfaces + +final class NetworkServiceProtocolSpy: NetworkServiceProtocol, @unchecked Sendable { + enum Method: Equatable { + case request + } + + var calledMethods: [Method] = [] + var requestResult: Result<(Data, HTTPURLResponse), Error>? + + func request(endpoint: APIEndpointProtocol) async throws -> (Data, HTTPURLResponse) { + calledMethods.append(.request) + + guard let result = requestResult else { + fatalError("requestResult not set") + } + + return try result.get() + } +} diff --git a/Projects/Home/Tests/Service/HomeEndpointTests.swift b/Projects/Home/Tests/Service/HomeEndpointTests.swift new file mode 100644 index 0000000..940af01 --- /dev/null +++ b/Projects/Home/Tests/Service/HomeEndpointTests.swift @@ -0,0 +1,57 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import NetworkingInterfaces +@testable import Home + +@Suite +struct HomeEndpointTests { + @Test("GIVEN fetchItems endpoint WHEN accessing path THEN returns correct path with parameters") + func testFetchItemsPath() throws { + let endpoint = HomeEndpoint.fetchItems(page: 1, limit: 10) + + #expect(endpoint.path == "/v1/exchange/map?start=1&limit=10") + } + + @Test("GIVEN fetchDetail endpoint WHEN accessing path THEN returns correct path with comma-separated IDs") + func testFetchDetailPath() throws { + let ids = ["1", "2", "3"] + + let endpoint = HomeEndpoint.fetchDetail(ids: ids) + + #expect(endpoint.path == "/v1/exchange/info?id=1,2,3") + } + + @Test("GIVEN fetchItems endpoint WHEN accessing method THEN returns GET method") + func testFetchItemsMethod() throws { + let endpoint = HomeEndpoint.fetchItems(page: 1, limit: 20) + + let method = endpoint.method + + #expect(method == .get) + } + + @Test("GIVEN fetchDetail endpoint WHEN accessing method THEN returns GET method") + func testFetchDetailMethod() throws { + let endpoint = HomeEndpoint.fetchDetail(ids: ["1"]) + + let method = endpoint.method + + #expect(method == .get) + } + + @Test("GIVEN any endpoint WHEN accessing headers THEN contains API key header") + func testEndpointHeaders() throws { + let endpoint = HomeEndpoint.fetchItems(page: 1, limit: 20) + + let headers = endpoint.headers + + #expect(headers?["X-CMC_PRO_API_KEY"] != nil) + } +} diff --git a/Projects/Home/Tests/Service/HomeServiceTests.swift b/Projects/Home/Tests/Service/HomeServiceTests.swift new file mode 100644 index 0000000..a809a58 --- /dev/null +++ b/Projects/Home/Tests/Service/HomeServiceTests.swift @@ -0,0 +1,185 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import Foundation +@testable import Home + +@Suite +struct HomeServiceTests { + @Test("GIVEN successful response WHEN fetchExchangesList is called THEN returns exchange summaries") + func testFetchExchangesListSuccess() async throws { + let (sut, networkSpy) = makeSut() + let mockResponse = """ + { + "status": { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": null, + "error_message": null, + "elapsed": 10, + "credit_count": 1 + }, + "data": [ + {"id": 1, "name": "Binance"}, + {"id": 2, "name": "Coinbase"} + ] + } + """ + let data = mockResponse.data(using: .utf8)! + let httpResponse = HTTPURLResponse( + url: URL(string: "https://api.example.com")!, + statusCode: 200, + httpVersion: nil, + headerFields: nil + )! + + networkSpy.requestResult = .success((data, httpResponse)) + + let result = try await sut.fetchExchangesList(page: 1, limit: 20) + + #expect(networkSpy.calledMethods == [.request]) + #expect(result.count == 2) + #expect(result[0].id == 1) + #expect(result[0].name == "Binance") + #expect(result[1].id == 2) + #expect(result[1].name == "Coinbase") + } + + @Test("GIVEN error response WHEN fetchExchangesList is called THEN throws network error") + func testFetchExchangesListNetworkError() async throws { + let (sut, networkSpy) = makeSut() + let expectedError = ServiceError.network(Status( + timestamp: "2024-01-01T00:00:00.000Z", + errorCode: 401, + errorMessage: "Invalid API Key", + elapsed: 10, + creditCount: 1 + )) + let mockResponse = """ + { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": 401, + "error_message": "Invalid API Key", + "elapsed": 10, + "credit_count": 1 + } + """ + let data = mockResponse.data(using: .utf8)! + let httpResponse = HTTPURLResponse( + url: URL(string: "https://api.example.com")!, + statusCode: 401, + httpVersion: nil, + headerFields: nil + )! + + networkSpy.requestResult = .success((data, httpResponse)) + + await #expect(throws: expectedError) { + _ = try await sut.fetchDetailsFor(ids: ["1"]) + } + #expect(networkSpy.calledMethods == [.request]) + } + + @Test("GIVEN successful response WHEN fetchDetailsFor is called THEN returns exchange details") + func testFetchDetailsForSuccess() async throws { + let (sut, networkSpy) = makeSut() + let mockResponse = """ + { + "status": { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": null, + "error_message": null, + "elapsed": 10, + "credit_count": 1 + }, + "data": { + "1": { + "id": 1, + "name": "Binance", + "description": "Binance Exchange", + "logo": "https://logo.url", + "spot_volume_usd": 1000000.0, + "maker_fee": 0.001, + "taker_fee": 0.002, + "date_launched": "2017-07-14", + "urls": { + "website": ["https://binance.com"], + "twitter": ["https://twitter.com/binance"] + } + } + } + } + """ + let data = mockResponse.data(using: .utf8)! + let httpResponse = HTTPURLResponse( + url: URL(string: "https://api.example.com")!, + statusCode: 200, + httpVersion: nil, + headerFields: nil + )! + + networkSpy.requestResult = .success((data, httpResponse)) + + let result = try await sut.fetchDetailsFor(ids: ["1"]) + + #expect(networkSpy.calledMethods == [.request]) + #expect(result.count == 1) + #expect(result[0].id == 1) + #expect(result[0].name == "Binance") + #expect(result[0].description == "Binance Exchange") + } + + @Test("GIVEN error response WHEN fetchDetailsFor is called THEN throws network error") + func testFetchDetailsForNetworkError() async throws { + let (sut, networkSpy) = makeSut() + let expectedError = ServiceError.network(Status( + timestamp: "2024-01-01T00:00:00.000Z", + errorCode: 500, + errorMessage: "Internal Server Error", + elapsed: 10, + creditCount: 1 + )) + + let mockResponse = """ + { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": 500, + "error_message": "Internal Server Error", + "elapsed": 10, + "credit_count": 1 + } + """ + let data = mockResponse.data(using: .utf8)! + let httpResponse = HTTPURLResponse( + url: URL(string: "https://api.example.com")!, + statusCode: 500, + httpVersion: nil, + headerFields: nil + )! + + networkSpy.requestResult = .success((data, httpResponse)) + + await #expect(throws: expectedError) { + _ = try await sut.fetchDetailsFor(ids: ["1"]) + } + #expect(networkSpy.calledMethods == [.request]) + } +} + +extension HomeServiceTests { + typealias SutAndDoubles = ( + sut: HomeService, + networkSpy: NetworkServiceProtocolSpy + ) + + func makeSut() -> SutAndDoubles { + let networkSpy = NetworkServiceProtocolSpy() + let sut = HomeService(networkService: networkSpy) + return (sut, networkSpy) + } +} diff --git a/Projects/Home/Tests/TestPlaceHolder.swift b/Projects/Home/Tests/TestPlaceHolder.swift deleted file mode 100644 index e69de29..0000000 diff --git a/Projects/Home/Tests/View/HomeViewControllerTests.swift b/Projects/Home/Tests/View/HomeViewControllerTests.swift new file mode 100644 index 0000000..27f39ce --- /dev/null +++ b/Projects/Home/Tests/View/HomeViewControllerTests.swift @@ -0,0 +1,91 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import UIKit +@testable import Home + +@MainActor +@Suite +struct HomeViewControllerTests { + @Test("GIVEN viewController WHEN viewDidLoad is called THEN sets up view and calls loadData") + func testViewDidLoad() throws { + let (sut, viewModelSpy) = makeSut() + + sut.loadView() + sut.viewDidLoad() + + #expect(sut.title == "Exchanges") + #expect(viewModelSpy.calledMethods.contains(.loadData)) + #expect(viewModelSpy.delegate != nil) + } + + @Test("GIVEN viewController WHEN tableView numberOfRows is called THEN returns viewModel numberOfItems") + func testTableViewNumberOfRows() throws { + let (sut, viewModelSpy) = makeSut() + viewModelSpy.numberOfItems = 5 + sut.loadView() + sut.viewDidLoad() + + let numberOfRows = sut.tableView(UITableView(), numberOfRowsInSection: 0) + + #expect(numberOfRows == 5) + } + + @Test("GIVEN viewController WHEN tableView cellForRow is called THEN returns configured cell") + func testTableViewCellForRow() throws { + let (sut, viewModelSpy) = makeSut() + let exchange = Exchange( + id: 1, + name: "Binance", + logo: "logo.url", + makerFee: 0.001, + takerFee: 0.002, + dateLaunched: "2017-07-14" + ) + viewModelSpy.itemsToReturn = [exchange] + viewModelSpy.numberOfItems = 1 + + sut.loadView() + sut.viewDidLoad() + + let tableView = UITableView() + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + + let cell = sut.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 0)) + + #expect(viewModelSpy.calledMethods.contains(.item)) + #expect(cell.textLabel?.text == nil || cell.contentConfiguration != nil) + } + + @Test("GIVEN viewController WHEN tableView didSelectRow is called THEN calls viewModel didSelectRow") + func testTableViewDidSelectRow() throws { + let (sut, viewModelSpy) = makeSut() + sut.loadView() + sut.viewDidLoad() + + let tableView = UITableView() + + sut.tableView(tableView, didSelectRowAt: IndexPath(row: 0, section: 0)) + + #expect(viewModelSpy.calledMethods.contains(.didSelectRow)) + } +} + +extension HomeViewControllerTests { + typealias SutAndDoubles = ( + sut: HomeViewController, + viewModelSpy: HomeViewModelSpy + ) + + func makeSut() -> SutAndDoubles { + let viewModelSpy = HomeViewModelSpy() + let sut = HomeViewController(viewModel: viewModelSpy) + return (sut, viewModelSpy) + } +} diff --git a/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift b/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift new file mode 100644 index 0000000..ff84313 --- /dev/null +++ b/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift @@ -0,0 +1,172 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import Foundation +@testable import Home + +@MainActor +@Suite +struct HomeViewModelTests { + + @Test("GIVEN empty state WHEN loadData is called THEN fetches exchanges and updates state to empty") + func testLoadDataSuccess() async throws { + let (sut, doubles) = makeSut() + doubles.serviceSpy.fetchExchangesListResult = .success([]) + + sut.loadData() + + try await Task.sleep(nanoseconds: 100_000_000) + + #expect(doubles.serviceSpy.calledMethods == [.fetchExchangesList]) + #expect(sut.numberOfItems == 0) + #expect(doubles.delegateSpy.calledMethods == [.didUpdateState(.loading), + .didUpdateState(.empty)]) + } + + @Test("GIVEN empty state WHEN loadData fails THEN updates state to error") + func testLoadDataError() async throws { + let (sut, doubles) = makeSut() + let error = NSError(domain: "test", code: 1, userInfo: [NSLocalizedDescriptionKey: "Network error"]) + doubles.serviceSpy.fetchExchangesListResult = .failure(error) + + sut.loadData() + + try await Task.sleep(nanoseconds: 100_000_000) + + #expect(doubles.serviceSpy.calledMethods.contains(.fetchExchangesList)) + #expect(sut.numberOfItems == 0) + #expect(doubles.delegateSpy.calledMethods == [.didUpdateState(.loading), + .didUpdateState(.error("Network error"))]) + } + + @Test("GIVEN empty state WHEN loadData returns empty array THEN updates state to empty") + func testLoadDataEmpty() async throws { + let (sut, doubles) = makeSut() + doubles.serviceSpy.fetchExchangesListResult = .success([]) + + sut.loadData() + + try await Task.sleep(nanoseconds: 100_000_000) + + #expect(doubles.serviceSpy.calledMethods == [.fetchExchangesList]) + #expect(sut.numberOfItems == 0) + #expect(doubles.delegateSpy.calledMethods == [.didUpdateState(.loading), + .didUpdateState(.empty)]) + } + + @Test("GIVEN valid index WHEN didSelectRow is called THEN notifies coordinator delegate") + func testDidSelectRow() async throws { + let (sut, doubles) = makeSut() + + let summaries = [ExchangeSummary(id: 1, name: "Binance")] + let detail = ExchangeDetail( + id: 1, + name: "Binance", + description: "Binance Exchange", + logo: "https://logo.url", + spotVolumeUsd: 1000000.0, + makerFee: 0.001, + takerFee: 0.002, + dateLaunched: "2017-07-14", + urls: ExchangeURLs(website: ["https://binance.com"], twitter: ["@binance"]) + ) + let exchange = Exchange(id: 1, + name: "Binance", + description: "Binance Exchange", + logo: "https://logo.url", + spotVolumeUsd: 1000000.0, + makerFee: 0.001, + takerFee: 0.002, + dateLaunched: "2017-07-14", + websiteUrl: "https://binance.com", + twitterUrl: "@binance" + ) + + doubles.serviceSpy.fetchExchangesListResult = .success(summaries) + doubles.serviceSpy.fetchDetailsForResult = .success([detail]) + + sut.loadData() + try await Task.sleep(nanoseconds: 100_000_000) + + sut.didSelectRow(at: 0) + + #expect(doubles.coordinatorDelegateSpy.calledMethods == [.navigateToDetails(exchange)]) + } + + @Test("GIVEN loaded exchanges WHEN item is requested at valid index THEN returns correct exchange") + func testItemAtIndex() async throws { + let (sut, doubles) = makeSut() + + let summaries = [ + ExchangeSummary(id: 1, name: "Binance"), + ExchangeSummary(id: 2, name: "Coinbase") + ] + let details = [ + ExchangeDetail( + id: 1, + name: "Binance", + description: "Binance Exchange", + logo: "https://logo1.url", + spotVolumeUsd: 1000000.0, + makerFee: 0.001, + takerFee: 0.002, + dateLaunched: "2017-07-14", + urls: ExchangeURLs(website: ["https://binance.com"], twitter: ["@binance"]) + ), + ExchangeDetail( + id: 2, + name: "Coinbase", + description: "Coinbase Exchange", + logo: "https://logo2.url", + spotVolumeUsd: 2000000.0, + makerFee: 0.003, + takerFee: 0.004, + dateLaunched: "2012-06-01", + urls: ExchangeURLs(website: ["https://coinbase.com"], twitter: ["@coinbase"]) + ) + ] + + doubles.serviceSpy.fetchExchangesListResult = .success(summaries) + doubles.serviceSpy.fetchDetailsForResult = .success(details) + + sut.loadData() + try await Task.sleep(nanoseconds: 100_000_000) + + let firstItem = sut.item(at: 0) + let secondItem = sut.item(at: 1) + + #expect(firstItem.id == 1) + #expect(firstItem.name == "Binance") + #expect(secondItem.id == 2) + #expect(secondItem.name == "Coinbase") + } +} + +extension HomeViewModelTests { + typealias SutAndDoubles = ( + sut: HomeViewModel, + doubles: ( + serviceSpy: HomeServiceProtocolSpy, + delegateSpy: HomeViewModelDelegateSpy, + coordinatorDelegateSpy: HomeViewModelCoordinatorDelegateSpy + ) + ) + + func makeSut() -> SutAndDoubles { + let serviceSpy = HomeServiceProtocolSpy() + let delegateSpy = HomeViewModelDelegateSpy() + let coordinatorDelegateSpy = HomeViewModelCoordinatorDelegateSpy() + + let sut = HomeViewModel(service: serviceSpy) + sut.delegate = delegateSpy + sut.coordinatorDelegate = coordinatorDelegateSpy + + return (sut, (serviceSpy, delegateSpy, coordinatorDelegateSpy)) + } +} From 1e99c7b99acb51a1bb8c5d2961dcf06c2f010e89 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Mon, 9 Feb 2026 11:27:34 -0300 Subject: [PATCH 10/16] feat: detail module (#25) --- .github/workflows/pr_status.yml | 6 ++ Projects/App/Project.swift | 4 ++ .../Assemblies/CoordinatorAssembly.swift | 18 ++++++ .../Sources/Coordinator/AppCoordinator.swift | 2 +- .../Tests/Application/AppDelegateTests.swift | 42 +++++++++++-- .../Interfaces/DetailCoordinating.swift | 12 ++++ Projects/Detail/Project.swift | 24 ++++++++ .../Coordinator/DetailCoordinator.swift | 42 +++++++++++++ Projects/Detail/Tests/PlaceHolder.swift | 0 .../{ => Coordinator}/HomeCoordinating.swift | 0 Projects/Home/Interfaces/Model/Exchange.swift | 61 +++++++++++++++++++ .../Interfaces/Model/ExchangeSummary.swift | 19 ++++++ Projects/Home/Interfaces/Model/Status.swift | 39 ++++++++++++ Projects/Home/Project.swift | 4 +- .../Sources/Coordinator/HomeCoordinator.swift | 12 +++- Projects/Home/Sources/Model/Exchange.swift | 61 ------------------- .../Model/ExchangeDetailResponse.swift | 1 + .../Home/Sources/Model/ExchangeResponse.swift | 1 + .../Home/Sources/Model/ExchangeSummary.swift | 14 ----- Projects/Home/Sources/Model/Status.swift | 27 -------- .../Protocols/HomeServiceProtocol.swift | 1 + .../HomeViewModelCoordinatorDelegate.swift | 3 +- .../Protocols/HomeViewModelProtocol.swift | 1 + .../Home/Sources/Service/HomeService.swift | 1 + .../Sources/ViewModel/HomeViewModel.swift | 9 +++ .../Doubles/HomeServiceProtocolSpy.swift | 2 + .../HomeViewModelCoordinatorDelegateSpy.swift | 2 + .../Home/Tests/Doubles/HomeViewModelSpy.swift | 2 + .../Home/Tests/Service/HomeServiceTests.swift | 4 +- .../Tests/View/HomeViewControllerTests.swift | 2 + .../Tests/ViewModel/HomeViewModelTests.swift | 4 +- .../Navigation/Testing/CoordinatorSpy.swift | 2 +- Tuist/Package.swift | 6 +- Workspace.swift | 3 +- 34 files changed, 315 insertions(+), 116 deletions(-) create mode 100644 Projects/Detail/Interfaces/DetailCoordinating.swift create mode 100644 Projects/Detail/Project.swift create mode 100644 Projects/Detail/Sources/Coordinator/DetailCoordinator.swift create mode 100644 Projects/Detail/Tests/PlaceHolder.swift rename Projects/Home/Interfaces/{ => Coordinator}/HomeCoordinating.swift (100%) create mode 100644 Projects/Home/Interfaces/Model/Exchange.swift create mode 100644 Projects/Home/Interfaces/Model/ExchangeSummary.swift create mode 100644 Projects/Home/Interfaces/Model/Status.swift delete mode 100644 Projects/Home/Sources/Model/Exchange.swift delete mode 100644 Projects/Home/Sources/Model/ExchangeSummary.swift delete mode 100644 Projects/Home/Sources/Model/Status.swift diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index 20bcb29..4827269 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -26,6 +26,8 @@ jobs: - 'Projects/DesignSystem/**' home: - 'Projects/Home/**' + detail: + - 'Projects/Detail/**' - name: Generate matrix id: matrix run: | @@ -45,6 +47,10 @@ jobs: if [ "${{ steps.filter.outputs.home }}" == "true" ]; then targets+=("Home") fi + + if [ "${{ steps.filter.outputs.detail }}" == "true" ]; then + targets+=("Detail") + fi if [ ${#targets[@]} -gt 0 ]; then matrix="{\"target\": [$(printf '"%s",' "${targets[@]}" | sed 's/,$//')]}" diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index bde3044..3d4769a 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -12,6 +12,10 @@ let dependecies: [TargetDependency] = [ path: "../Home"), .project(target: "HomeInterfaces", path: "../Home"), + .project(target: "Detail", + path: "../Detail"), + .project(target: "DetailInterfaces", + path: "../Detail"), .project(target: "NavigationInterfaces", path: "../Navigation"), .external(name: "Networking"), diff --git a/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift b/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift index 6294188..04071b4 100644 --- a/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift +++ b/Projects/App/Sources/Assemblies/CoordinatorAssembly.swift @@ -6,6 +6,8 @@ // // import DependencyInjectionInterfaces +import Detail +import DetailInterfaces import HomeInterfaces import Home import NavigationInterfaces @@ -31,5 +33,21 @@ public struct CoordinatorAssembly { return HomeCoordinator(parentCoordinator: parentCoordinator, navigationController: navigationController) } + + injector.register(DetailCoordinating.self) { (_, arg: (UINavigationController, Coordinator?, Exchange)) in + let (navigationController, parentCoordinator, exchange) = arg + + return DetailCoordinator(parentCoordinator: parentCoordinator, + navigationController: navigationController, + exchange: exchange) + } + + injector.register(DetailCoordinating.self) { (_, arg: (UINavigationController, Coordinator?, Int)) in + let (navigationController, parentCoordinator, exchangeId) = arg + + return DetailCoordinator(parentCoordinator: parentCoordinator, + navigationController: navigationController, + exchangeId: exchangeId) + } } } diff --git a/Projects/App/Sources/Coordinator/AppCoordinator.swift b/Projects/App/Sources/Coordinator/AppCoordinator.swift index 124ee30..a364e14 100644 --- a/Projects/App/Sources/Coordinator/AppCoordinator.swift +++ b/Projects/App/Sources/Coordinator/AppCoordinator.swift @@ -29,7 +29,7 @@ final class AppCoordinator: AppCoordinating { let homeCoordinator = resolver.resolve(HomeCoordinating.self, argument: arg) - + children.append(homeCoordinator) homeCoordinator.start() } } diff --git a/Projects/App/Tests/Application/AppDelegateTests.swift b/Projects/App/Tests/Application/AppDelegateTests.swift index 9f7cd17..85c87ef 100644 --- a/Projects/App/Tests/Application/AppDelegateTests.swift +++ b/Projects/App/Tests/Application/AppDelegateTests.swift @@ -8,9 +8,11 @@ import Testing import DependencyInjectionInterfaces -import NetworkingInterfaces +import DetailInterfaces import HomeInterfaces import NavigationInterfaces +import NavigationTesting +import NetworkingInterfaces import UIKit @testable import App @@ -62,15 +64,45 @@ struct AppDelegateTests { func homeCoordinatorRegister() async throws { #expect(throws: Never.self) { let navigation = UINavigationController() - let parentCoordinator: Coordinator? = SharedContainer + let parentCoordinator: Coordinator? = CoordinatorSpy(children: [], + navigationController: navigation) + + _ = SharedContainer .shared .resolver() - .resolve(AppCoordinating.self, argument: navigation) - + .resolve(HomeCoordinating.self, argument: (navigation, parentCoordinator)) + } + } + + @Test("GIVEN AppDelegate initialize THEN it SHOULD register DI DetailCoordinating with Exchange") + func detailCoordinatorRegister() async throws { + #expect(throws: Never.self) { + let navigation = UINavigationController() + let exchange = Exchange(summary: .init(id: 0, name: "exchange")) + + let parentCoordinator: Coordinator? = CoordinatorSpy(children: [], + navigationController: navigation) + _ = SharedContainer .shared .resolver() - .resolve(HomeCoordinating.self, argument: (navigation, parentCoordinator)) + .resolve(DetailCoordinating.self, argument: (navigation, parentCoordinator, exchange)) + } + } + + @Test("GIVEN AppDelegate initialize THEN it SHOULD register DI DetailCoordinating with Exchange identifier") + func detailWithIdentifierCoordinatorRegister() async throws { + #expect(throws: Never.self) { + let navigation = UINavigationController() + let exchangeId: Int = 21 + + let parentCoordinator: Coordinator? = CoordinatorSpy(children: [], + navigationController: navigation) + + _ = SharedContainer + .shared + .resolver() + .resolve(DetailCoordinating.self, argument: (navigation, parentCoordinator, exchangeId)) } } } diff --git a/Projects/Detail/Interfaces/DetailCoordinating.swift b/Projects/Detail/Interfaces/DetailCoordinating.swift new file mode 100644 index 0000000..0360436 --- /dev/null +++ b/Projects/Detail/Interfaces/DetailCoordinating.swift @@ -0,0 +1,12 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import NavigationInterfaces +import UIKit + +public protocol DetailCoordinating: Coordinator {} diff --git a/Projects/Detail/Project.swift b/Projects/Detail/Project.swift new file mode 100644 index 0000000..9214e15 --- /dev/null +++ b/Projects/Detail/Project.swift @@ -0,0 +1,24 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let moduleName = "Detail" + +let dependecies: [TargetDependency] = [ + .project(target: "DependencyInjectionInterfaces", + path: "../DependencyInjection"), + .project(target: "DesignSystem", + path: "../DesignSystem"), + .project(target: "HomeInterfaces", + path: "../Home"), + .external(name: "NetworkingInterfaces"), +] + +let interfaceDependecies: [TargetDependency] = [ + .project(target: "NavigationInterfaces", + path: "../Navigation"), +] + +let project = Project.templateModule(named: moduleName, + targets: [.source, .interfaces, .test], + dependencies: dependecies, + interfaceDependecies: interfaceDependecies) diff --git a/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift b/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift new file mode 100644 index 0000000..e3525b5 --- /dev/null +++ b/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift @@ -0,0 +1,42 @@ +import UIKit +import DetailInterfaces +import DependencyInjectionInterfaces +import HomeInterfaces +import NavigationInterfaces +import NetworkingInterfaces + +@MainActor +public final class DetailCoordinator: DetailCoordinating { + // MARK: - Properties + + public weak var parentCoordinator: Coordinator? + public var children: [Coordinator] = [] + public var navigationController: UINavigationController + + private var exchange: Exchange? + private var exchangeId: Int? + + // MARK: - Initialization + + public init(parentCoordinator: Coordinator?, + navigationController: UINavigationController, + exchange: Exchange) { + self.parentCoordinator = parentCoordinator + self.navigationController = navigationController + self.exchange = exchange + } + + public init(parentCoordinator: Coordinator?, + navigationController: UINavigationController, + exchangeId: Int) { + self.parentCoordinator = parentCoordinator + self.navigationController = navigationController + self.exchangeId = exchangeId + } + + // MARK: - DetailCoordinating + + public func start() { + + } +} diff --git a/Projects/Detail/Tests/PlaceHolder.swift b/Projects/Detail/Tests/PlaceHolder.swift new file mode 100644 index 0000000..e69de29 diff --git a/Projects/Home/Interfaces/HomeCoordinating.swift b/Projects/Home/Interfaces/Coordinator/HomeCoordinating.swift similarity index 100% rename from Projects/Home/Interfaces/HomeCoordinating.swift rename to Projects/Home/Interfaces/Coordinator/HomeCoordinating.swift diff --git a/Projects/Home/Interfaces/Model/Exchange.swift b/Projects/Home/Interfaces/Model/Exchange.swift new file mode 100644 index 0000000..bf63b73 --- /dev/null +++ b/Projects/Home/Interfaces/Model/Exchange.swift @@ -0,0 +1,61 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public struct Exchange: Equatable, Identifiable { + public let id: Int + public let name: String + public let description: String? + public let logo: String + public let spotVolumeUsd: Double? + public let makerFee: Double + public let takerFee: Double + public let dateLaunched: String + public let websiteUrl: String? + public let twitterUrl: String? + + public let isLoadingDetails: Bool + + public init(id: Int, + name: String, + description: String? = nil, + logo: String, + spotVolumeUsd: Double? = nil, + makerFee: Double, + takerFee: Double, + dateLaunched: String, + websiteUrl: String? = nil, + twitterUrl: String? = nil) { + self.id = id + self.name = name + self.description = description + self.logo = logo + self.spotVolumeUsd = spotVolumeUsd + self.makerFee = makerFee + self.takerFee = takerFee + self.dateLaunched = dateLaunched + self.websiteUrl = websiteUrl + self.twitterUrl = twitterUrl + self.isLoadingDetails = false + } + + public init(summary: ExchangeSummary) { + self.id = summary.id + self.name = summary.name + self.description = nil + self.logo = "" + self.spotVolumeUsd = nil + self.makerFee = 0.0 + self.takerFee = 0.0 + self.dateLaunched = "" + self.websiteUrl = nil + self.twitterUrl = nil + self.isLoadingDetails = true + } +} diff --git a/Projects/Home/Interfaces/Model/ExchangeSummary.swift b/Projects/Home/Interfaces/Model/ExchangeSummary.swift new file mode 100644 index 0000000..c38c402 --- /dev/null +++ b/Projects/Home/Interfaces/Model/ExchangeSummary.swift @@ -0,0 +1,19 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public struct ExchangeSummary: Sendable, Equatable, Codable { + public let id: Int + public let name: String + + public init(id: Int, name: String) { + self.id = id + self.name = name + } +} diff --git a/Projects/Home/Interfaces/Model/Status.swift b/Projects/Home/Interfaces/Model/Status.swift new file mode 100644 index 0000000..7de661a --- /dev/null +++ b/Projects/Home/Interfaces/Model/Status.swift @@ -0,0 +1,39 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +public struct Status: Equatable { + let timestamp: String + let errorCode: Int? + let errorMessage: String? + let elapsed: Int + let creditCount: Int + + public init(timestamp: String, + errorCode: Int? = nil, + errorMessage: String? = nil, + elapsed: Int, + creditCount: Int) { + self.timestamp = timestamp + self.errorCode = errorCode + self.errorMessage = errorMessage + self.elapsed = elapsed + self.creditCount = creditCount + } +} + +extension Status: Codable { + public enum CodingKeys: String, CodingKey { + case timestamp + case errorCode = "error_code" + case errorMessage = "error_message" + case elapsed + case creditCount = "credit_count" + } +} diff --git a/Projects/Home/Project.swift b/Projects/Home/Project.swift index b1e2751..42584f7 100644 --- a/Projects/Home/Project.swift +++ b/Projects/Home/Project.swift @@ -7,7 +7,9 @@ let dependecies: [TargetDependency] = [ .project(target: "DependencyInjectionInterfaces", path: "../DependencyInjection"), .project(target: "DesignSystem", - path: "../DesignSystem"), + path: "../DesignSystem"), + .project(target: "DetailInterfaces", + path: "../Detail"), .external(name: "NetworkingInterfaces"), ] diff --git a/Projects/Home/Sources/Coordinator/HomeCoordinator.swift b/Projects/Home/Sources/Coordinator/HomeCoordinator.swift index 2206557..5c3e911 100644 --- a/Projects/Home/Sources/Coordinator/HomeCoordinator.swift +++ b/Projects/Home/Sources/Coordinator/HomeCoordinator.swift @@ -7,6 +7,7 @@ // import DependencyInjectionInterfaces +import DetailInterfaces import HomeInterfaces import NavigationInterfaces import NetworkingInterfaces @@ -35,5 +36,14 @@ public final class HomeCoordinator: HomeCoordinating { } extension HomeCoordinator: HomeViewModelCoordinatorDelegate { - func navigateToDetails(of exchange: Exchange) {} + func navigateToDetails(of exchange: Exchange) { + let resolver = SharedContainer.shared.resolver() + let arg: (UINavigationController, Coordinator?, Exchange) = (navigationController, self, exchange) + + let detailCoordinator = resolver.resolve(DetailCoordinating.self, + argument: arg) + + children.append(detailCoordinator) + detailCoordinator.start() + } } diff --git a/Projects/Home/Sources/Model/Exchange.swift b/Projects/Home/Sources/Model/Exchange.swift deleted file mode 100644 index bb5e0c9..0000000 --- a/Projects/Home/Sources/Model/Exchange.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// -// Created by Vitor Conceicao. -// -// github.com/vitor-rc1 -// -// - -import Foundation - -struct Exchange: Equatable, Identifiable { - let id: Int - let name: String - let description: String? - let logo: String - let spotVolumeUsd: Double? - let makerFee: Double - let takerFee: Double - let dateLaunched: String - let websiteUrl: String? - let twitterUrl: String? - - let isLoadingDetails: Bool - - init(id: Int, - name: String, - description: String? = nil, - logo: String, - spotVolumeUsd: Double? = nil, - makerFee: Double, - takerFee: Double, - dateLaunched: String, - websiteUrl: String? = nil, - twitterUrl: String? = nil) { - self.id = id - self.name = name - self.description = description - self.logo = logo - self.spotVolumeUsd = spotVolumeUsd - self.makerFee = makerFee - self.takerFee = takerFee - self.dateLaunched = dateLaunched - self.websiteUrl = websiteUrl - self.twitterUrl = twitterUrl - self.isLoadingDetails = false - } - - init(summary: ExchangeSummary) { - self.id = summary.id - self.name = summary.name - self.description = nil - self.logo = "" - self.spotVolumeUsd = nil - self.makerFee = 0.0 - self.takerFee = 0.0 - self.dateLaunched = "" - self.websiteUrl = nil - self.twitterUrl = nil - self.isLoadingDetails = true - } -} diff --git a/Projects/Home/Sources/Model/ExchangeDetailResponse.swift b/Projects/Home/Sources/Model/ExchangeDetailResponse.swift index dd4bd38..08d809e 100644 --- a/Projects/Home/Sources/Model/ExchangeDetailResponse.swift +++ b/Projects/Home/Sources/Model/ExchangeDetailResponse.swift @@ -7,6 +7,7 @@ // import Foundation +import HomeInterfaces struct ExchangeDetailResponse: Codable { let status: Status diff --git a/Projects/Home/Sources/Model/ExchangeResponse.swift b/Projects/Home/Sources/Model/ExchangeResponse.swift index 318aa80..8bdc7a5 100644 --- a/Projects/Home/Sources/Model/ExchangeResponse.swift +++ b/Projects/Home/Sources/Model/ExchangeResponse.swift @@ -7,6 +7,7 @@ // import Foundation +import HomeInterfaces struct ExchangeResponse: Codable { let status: Status diff --git a/Projects/Home/Sources/Model/ExchangeSummary.swift b/Projects/Home/Sources/Model/ExchangeSummary.swift deleted file mode 100644 index 57f83e1..0000000 --- a/Projects/Home/Sources/Model/ExchangeSummary.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// -// Created by Vitor Conceicao. -// -// github.com/vitor-rc1 -// -// - -import Foundation - -struct ExchangeSummary: Equatable, Codable { - let id: Int - let name: String -} diff --git a/Projects/Home/Sources/Model/Status.swift b/Projects/Home/Sources/Model/Status.swift deleted file mode 100644 index f848afa..0000000 --- a/Projects/Home/Sources/Model/Status.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// -// Created by Vitor Conceicao. -// -// github.com/vitor-rc1 -// -// - -import Foundation - -struct Status: Equatable { - let timestamp: String - let errorCode: Int? - let errorMessage: String? - let elapsed: Int - let creditCount: Int -} - -extension Status: Codable { - enum CodingKeys: String, CodingKey { - case timestamp - case errorCode = "error_code" - case errorMessage = "error_message" - case elapsed - case creditCount = "credit_count" - } -} diff --git a/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift b/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift index 00fbce6..d541887 100644 --- a/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift +++ b/Projects/Home/Sources/Protocols/HomeServiceProtocol.swift @@ -6,6 +6,7 @@ // // +import HomeInterfaces import Foundation protocol HomeServiceProtocol: AnyObject, Sendable { diff --git a/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift b/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift index 53df5d6..a5ef733 100644 --- a/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift +++ b/Projects/Home/Sources/Protocols/HomeViewModelCoordinatorDelegate.swift @@ -5,8 +5,9 @@ // github.com/vitor-rc1 // // - + import Foundation +import HomeInterfaces @MainActor protocol HomeViewModelCoordinatorDelegate: AnyObject { diff --git a/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift b/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift index 5d6fe8a..d8cb8c3 100644 --- a/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift +++ b/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift @@ -6,6 +6,7 @@ // // +import HomeInterfaces import Foundation @MainActor diff --git a/Projects/Home/Sources/Service/HomeService.swift b/Projects/Home/Sources/Service/HomeService.swift index b07ed9c..69b70a6 100644 --- a/Projects/Home/Sources/Service/HomeService.swift +++ b/Projects/Home/Sources/Service/HomeService.swift @@ -7,6 +7,7 @@ // import Foundation +import HomeInterfaces import NetworkingInterfaces enum ServiceError: Error, Equatable { diff --git a/Projects/Home/Sources/ViewModel/HomeViewModel.swift b/Projects/Home/Sources/ViewModel/HomeViewModel.swift index c237f41..5385a63 100644 --- a/Projects/Home/Sources/ViewModel/HomeViewModel.swift +++ b/Projects/Home/Sources/ViewModel/HomeViewModel.swift @@ -1,3 +1,12 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import HomeInterfaces import Foundation @MainActor diff --git a/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift b/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift index c801368..a98bf23 100644 --- a/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift +++ b/Projects/Home/Tests/Doubles/HomeServiceProtocolSpy.swift @@ -7,6 +7,8 @@ // import Foundation +import HomeInterfaces + @testable import Home @MainActor diff --git a/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift b/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift index 8ca5226..851c331 100644 --- a/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift +++ b/Projects/Home/Tests/Doubles/HomeViewModelCoordinatorDelegateSpy.swift @@ -7,6 +7,8 @@ // import Foundation +import HomeInterfaces + @testable import Home @MainActor diff --git a/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift b/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift index 28f4feb..7f94512 100644 --- a/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift +++ b/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift @@ -7,6 +7,8 @@ // import Foundation +import HomeInterfaces + @testable import Home @MainActor diff --git a/Projects/Home/Tests/Service/HomeServiceTests.swift b/Projects/Home/Tests/Service/HomeServiceTests.swift index a809a58..728d73c 100644 --- a/Projects/Home/Tests/Service/HomeServiceTests.swift +++ b/Projects/Home/Tests/Service/HomeServiceTests.swift @@ -6,8 +6,10 @@ // // -import Testing +import HomeInterfaces import Foundation +import Testing + @testable import Home @Suite diff --git a/Projects/Home/Tests/View/HomeViewControllerTests.swift b/Projects/Home/Tests/View/HomeViewControllerTests.swift index 27f39ce..6489f1b 100644 --- a/Projects/Home/Tests/View/HomeViewControllerTests.swift +++ b/Projects/Home/Tests/View/HomeViewControllerTests.swift @@ -6,8 +6,10 @@ // // +import HomeInterfaces import Testing import UIKit + @testable import Home @MainActor diff --git a/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift b/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift index ff84313..9b182c0 100644 --- a/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift +++ b/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift @@ -6,8 +6,10 @@ // // -import Testing import Foundation +import HomeInterfaces +import Testing + @testable import Home @MainActor diff --git a/Projects/Navigation/Testing/CoordinatorSpy.swift b/Projects/Navigation/Testing/CoordinatorSpy.swift index 2c0ee6f..0aa20d9 100644 --- a/Projects/Navigation/Testing/CoordinatorSpy.swift +++ b/Projects/Navigation/Testing/CoordinatorSpy.swift @@ -20,7 +20,7 @@ public final class CoordinatorSpy: Coordinator { public var navigationController: UINavigationController public init(parentCoordinator: Coordinator? = nil, - children: [Coordinator], + children: [Coordinator] = [], navigationController: UINavigationController) { self.parentCoordinator = parentCoordinator self.children = children diff --git a/Tuist/Package.swift b/Tuist/Package.swift index f545677..9cc58a7 100644 --- a/Tuist/Package.swift +++ b/Tuist/Package.swift @@ -5,7 +5,11 @@ import PackageDescription import ProjectDescription let packageSettings = PackageSettings( - productTypes: [:] + productTypes: [ + "Swinject": .framework, + "NetworkingInterfaces": .framework, + "Networking": .framework + ] ) #endif diff --git a/Workspace.swift b/Workspace.swift index de4324c..cd635ed 100644 --- a/Workspace.swift +++ b/Workspace.swift @@ -7,7 +7,8 @@ let workspace = Workspace( "./Projects/App", "./Projects/DependencyInjection", "./Projects/DesignSystem", - "./Projects/Home" + "./Projects/Home", + "./Projects/Detail" ], schemes: [], generationOptions: .options(autogeneratedWorkspaceSchemes: .disabled) From 699173d84b45660d958a14f5a151a9ab615928bc Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Mon, 9 Feb 2026 11:59:06 -0300 Subject: [PATCH 11/16] tests: add home coordinator tests (#26) --- .../Testing/DependencyInjectorSpy.swift | 4 - Projects/Detail/Project.swift | 2 +- .../Coordinator/DetailCoordinatingSpy.swift | 27 ++++++ Projects/Home/Project.swift | 10 +++ .../Coordinator/HomeCoordinatingSpy.swift | 2 +- .../Coordinator/HomeCoordinatorTests.swift | 87 +++++++++++++++++++ .../Testing/NavigationControllerSpy.swift | 32 +++++++ 7 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 Projects/Detail/Testing/Coordinator/DetailCoordinatingSpy.swift create mode 100644 Projects/Home/Tests/Coordinator/HomeCoordinatorTests.swift create mode 100644 Projects/Navigation/Testing/NavigationControllerSpy.swift diff --git a/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift b/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift index fb1510c..b5815e9 100644 --- a/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift +++ b/Projects/DependencyInjection/Testing/DependencyInjectorSpy.swift @@ -12,8 +12,6 @@ public final class DependencyInjectorSpy: DependencyInjector { public init() {} public enum Method { - case register - case registerWithArgument case resolve case resolveWithArgument } @@ -30,14 +28,12 @@ public final class DependencyInjectorSpy: DependencyInjector { public func register(_ serviceType: Service.Type, factory: @escaping (DependencyResolver) -> Service) { - calledMethods.append(.register) let identifier = typeIdentifier(serviceType) registeredServices[identifier] = factory } public func register(_ serviceType: Service.Type, factory: @escaping (DependencyResolver, Argument) -> Service) { - calledMethods.append(.registerWithArgument) let identifier = typeIdentifier(serviceType) registeredServicesWithArgument[identifier] = factory } diff --git a/Projects/Detail/Project.swift b/Projects/Detail/Project.swift index 9214e15..c37b341 100644 --- a/Projects/Detail/Project.swift +++ b/Projects/Detail/Project.swift @@ -19,6 +19,6 @@ let interfaceDependecies: [TargetDependency] = [ ] let project = Project.templateModule(named: moduleName, - targets: [.source, .interfaces, .test], + targets: [.source, .interfaces, .test, .testing], dependencies: dependecies, interfaceDependecies: interfaceDependecies) diff --git a/Projects/Detail/Testing/Coordinator/DetailCoordinatingSpy.swift b/Projects/Detail/Testing/Coordinator/DetailCoordinatingSpy.swift new file mode 100644 index 0000000..7ee637a --- /dev/null +++ b/Projects/Detail/Testing/Coordinator/DetailCoordinatingSpy.swift @@ -0,0 +1,27 @@ +import UIKit +import DetailInterfaces +import NavigationInterfaces + +@MainActor +public final class DetailCoordinatingSpy: DetailCoordinating { + public enum Method: Equatable { + case start + } + + public var calledMethods: [Method] = [] + public var parentCoordinator: Coordinator? + public var children: [Coordinator] = [] + public var navigationController: UINavigationController + + public init(parentCoordinator: Coordinator? = nil, + children: [Coordinator], + navigationController: UINavigationController) { + self.parentCoordinator = parentCoordinator + self.children = children + self.navigationController = navigationController + } + + public func start() { + calledMethods.append(.start) + } +} diff --git a/Projects/Home/Project.swift b/Projects/Home/Project.swift index 42584f7..9db5cf3 100644 --- a/Projects/Home/Project.swift +++ b/Projects/Home/Project.swift @@ -18,7 +18,17 @@ let interfaceDependecies: [TargetDependency] = [ path: "../Navigation"), ] +let testsDependecies: [TargetDependency] = [ + .project(target: "DependencyInjectionTesting", + path: "../DependencyInjection"), + .project(target: "DetailTesting", + path: "../Detail"), + .project(target: "NavigationTesting", + path: "../Navigation"), +] + let project = Project.templateModule(named: moduleName, targets: [.source,. interfaces, .test, .testing], dependencies: dependecies, + testDependencies: testsDependecies, interfaceDependecies: interfaceDependecies) diff --git a/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift b/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift index 218d4cf..b4c00d3 100644 --- a/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift +++ b/Projects/Home/Testing/Coordinator/HomeCoordinatingSpy.swift @@ -11,7 +11,7 @@ import NavigationInterfaces import UIKit public final class HomeCoordinatingSpy: HomeCoordinating { - public enum Method { + public enum Method: Equatable { case start } diff --git a/Projects/Home/Tests/Coordinator/HomeCoordinatorTests.swift b/Projects/Home/Tests/Coordinator/HomeCoordinatorTests.swift new file mode 100644 index 0000000..e789bdd --- /dev/null +++ b/Projects/Home/Tests/Coordinator/HomeCoordinatorTests.swift @@ -0,0 +1,87 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import DependencyInjectionInterfaces +import DependencyInjectionTesting +import DetailInterfaces +import DetailTesting +import HomeInterfaces +import NavigationInterfaces +import NavigationTesting +import NetworkingInterfaces +import Testing +import UIKit + +@testable import Home + +@MainActor +@Suite +struct HomeCoordinatorTestsTests { + + // MARK: - Start Tests + + @Test("GIVEN HomeCoordinator WHEN start is called THEN push home") + func startNavigateToHome() { + let (sut, doubles) = makeSut() + doubles.injectorSpy + .register(NetworkServiceProtocol.self) { _ in + doubles.networkSpy + } + + sut.start() + + #expect(doubles.injectorSpy.calledMethods == [.resolve]) + #expect(doubles.navigationController.calledMethods == [.pushViewController]) + } + + @Test("GIVEN HomeCoordinator WHEN navigateToDetails is called THEN start details") + func avigateToDetailsNavitageToDetails() { + let (sut, doubles) = makeSut() + let navigationController = doubles.navigationController + let detailsCoordinatingSpy = DetailCoordinatingSpy(children: [], + navigationController: navigationController) + + doubles.injectorSpy + .register(DetailCoordinating.self) { (_, arg: (UINavigationController, Coordinator?, Exchange)) in + detailsCoordinatingSpy + } + + sut.navigateToDetails(of: .init(summary: .init(id: 1, name: "")) ) + + #expect(doubles.injectorSpy.calledMethods == [.resolveWithArgument]) + #expect(detailsCoordinatingSpy.calledMethods == [.start]) + } +} + +extension HomeCoordinatorTestsTests { + typealias SutAndDoubles = ( + sut: HomeCoordinator, + doubles: ( + networkSpy: NetworkServiceProtocolSpy, + coordinatorSpy: CoordinatorSpy, + navigationController: NavigationControllerSpy, + injectorSpy: DependencyInjectorSpy + ) + ) + + func makeSut() -> SutAndDoubles { + let navigationController = NavigationControllerSpy() + let coordinatorSpy = CoordinatorSpy(navigationController: navigationController) + let network = NetworkServiceProtocolSpy() + let injectorSpy = DependencyInjectorSpy() + SharedContainer.shared.setInjector(injectorSpy) + + let sut = HomeCoordinator(parentCoordinator: coordinatorSpy, + navigationController: navigationController) + + return (sut, (network, + coordinatorSpy, + navigationController, + injectorSpy)) + } +} diff --git a/Projects/Navigation/Testing/NavigationControllerSpy.swift b/Projects/Navigation/Testing/NavigationControllerSpy.swift new file mode 100644 index 0000000..01756ee --- /dev/null +++ b/Projects/Navigation/Testing/NavigationControllerSpy.swift @@ -0,0 +1,32 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit + +public final class NavigationControllerSpy: UINavigationController { + public enum Method: Equatable { + case pushViewController + case present + } + + public private(set) var calledMethods: [Method] = [] + + public var pushViewControllerPassed: UIViewController? + public override func pushViewController(_ viewController: UIViewController, animated: Bool) { + calledMethods.append(.pushViewController) + self.pushViewControllerPassed = viewController + } + + public var presentViewControllerPassed: UIViewController? + public override func present(_ viewControllerToPresent: UIViewController, + animated flag: Bool, + completion: (() -> Void)? = nil) { + calledMethods.append(.present) + self.presentViewControllerPassed = viewControllerToPresent + } +} From 9287f56239589f323bca02bbc67dcb9fca84e736 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Mon, 9 Feb 2026 19:11:49 -0300 Subject: [PATCH 12/16] feat: detail scene (#27) --- Projects/Detail/Project.swift | 8 + .../Coordinator/DetailCoordinator.swift | 22 ++ Projects/Detail/Sources/Model/Asset.swift | 23 ++ .../Sources/Model/DetailViewState.swift | 18 ++ .../Model/ExchangeAssetsResponse.swift | 41 +++ .../Sources/Model/ExchangeDetailModel.swift | 40 +++ .../Protocols/DetailServiceProtocol.swift | 13 + .../DetailViewModelCoordinatorDelegate.swift | 14 ++ .../Protocols/DetailViewModelDelegate.swift | 14 ++ .../Protocols/DetailViewModelProtocol.swift | 21 ++ .../Sources/Service/DetailEndpoint.swift | 35 +++ .../Sources/Service/DetailService.swift | 58 +++++ .../Sources/View/AssetTableViewCell.swift | 136 ++++++++++ .../Sources/View/DetailHeaderView.swift | 236 ++++++++++++++++++ .../Sources/View/DetailViewController.swift | 211 ++++++++++++++++ .../Sources/View/HeaderSectionView.swift | 77 ++++++ .../Sources/ViewModel/DetailViewModel.swift | 79 ++++++ .../Coordinator/DetailCoordinatorTests.swift | 111 ++++++++ .../Doubles/DetailServiceProtocolSpy.swift | 32 +++ .../Tests/Doubles/DetailViewModelSpy.swift | 38 +++ .../Doubles/NetworkServiceProtocolSpy.swift | 29 +++ Projects/Detail/Tests/PlaceHolder.swift | 0 .../Tests/Service/DetailEndpointTests.swift | 55 ++++ .../Tests/Service/DetailServiceTests.swift | 146 +++++++++++ ...etailViewModelCoordinatorDelegateSpy.swift | 23 ++ .../Service/DetailViewModelDelegateSpy.swift | 23 ++ .../View/DetailViewControllerTests.swift | 157 ++++++++++++ .../ViewModel/DetailViewModelTests.swift | 181 ++++++++++++++ Projects/Home/Interfaces/Model/Status.swift | 2 +- 29 files changed, 1842 insertions(+), 1 deletion(-) create mode 100644 Projects/Detail/Sources/Model/Asset.swift create mode 100644 Projects/Detail/Sources/Model/DetailViewState.swift create mode 100644 Projects/Detail/Sources/Model/ExchangeAssetsResponse.swift create mode 100644 Projects/Detail/Sources/Model/ExchangeDetailModel.swift create mode 100644 Projects/Detail/Sources/Protocols/DetailServiceProtocol.swift create mode 100644 Projects/Detail/Sources/Protocols/DetailViewModelCoordinatorDelegate.swift create mode 100644 Projects/Detail/Sources/Protocols/DetailViewModelDelegate.swift create mode 100644 Projects/Detail/Sources/Protocols/DetailViewModelProtocol.swift create mode 100644 Projects/Detail/Sources/Service/DetailEndpoint.swift create mode 100644 Projects/Detail/Sources/Service/DetailService.swift create mode 100644 Projects/Detail/Sources/View/AssetTableViewCell.swift create mode 100644 Projects/Detail/Sources/View/DetailHeaderView.swift create mode 100644 Projects/Detail/Sources/View/DetailViewController.swift create mode 100644 Projects/Detail/Sources/View/HeaderSectionView.swift create mode 100644 Projects/Detail/Sources/ViewModel/DetailViewModel.swift create mode 100644 Projects/Detail/Tests/Coordinator/DetailCoordinatorTests.swift create mode 100644 Projects/Detail/Tests/Doubles/DetailServiceProtocolSpy.swift create mode 100644 Projects/Detail/Tests/Doubles/DetailViewModelSpy.swift create mode 100644 Projects/Detail/Tests/Doubles/NetworkServiceProtocolSpy.swift delete mode 100644 Projects/Detail/Tests/PlaceHolder.swift create mode 100644 Projects/Detail/Tests/Service/DetailEndpointTests.swift create mode 100644 Projects/Detail/Tests/Service/DetailServiceTests.swift create mode 100644 Projects/Detail/Tests/Service/DetailViewModelCoordinatorDelegateSpy.swift create mode 100644 Projects/Detail/Tests/Service/DetailViewModelDelegateSpy.swift create mode 100644 Projects/Detail/Tests/View/DetailViewControllerTests.swift create mode 100644 Projects/Detail/Tests/ViewModel/DetailViewModelTests.swift diff --git a/Projects/Detail/Project.swift b/Projects/Detail/Project.swift index c37b341..dd70811 100644 --- a/Projects/Detail/Project.swift +++ b/Projects/Detail/Project.swift @@ -18,7 +18,15 @@ let interfaceDependecies: [TargetDependency] = [ path: "../Navigation"), ] +let testsDependecies: [TargetDependency] = [ + .project(target: "DependencyInjectionTesting", + path: "../DependencyInjection"), + .project(target: "NavigationTesting", + path: "../Navigation"), +] + let project = Project.templateModule(named: moduleName, targets: [.source, .interfaces, .test, .testing], dependencies: dependecies, + testDependencies: testsDependecies, interfaceDependecies: interfaceDependecies) diff --git a/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift b/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift index e3525b5..91962a5 100644 --- a/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift +++ b/Projects/Detail/Sources/Coordinator/DetailCoordinator.swift @@ -37,6 +37,28 @@ public final class DetailCoordinator: DetailCoordinating { // MARK: - DetailCoordinating public func start() { + let resolver = SharedContainer.shared.resolver() + let networkService: NetworkServiceProtocol = resolver.resolve() + let detailService = DetailService(networkService: networkService) + let viewModel = DetailViewModel(service: detailService) + if let exchange { + viewModel.configure(with: exchange) + } + if let exchangeId { + viewModel.configure(with: exchangeId) + } + viewModel.coordinatorDelegate = self + let viewController = DetailViewController(viewModel: viewModel) + + navigationController.pushViewController(viewController, animated: true) + } +} + +// MARK: - DetailViewModelCoordinatorDelegate + +extension DetailCoordinator: DetailViewModelCoordinatorDelegate { + public func didRequestOpenURL(_ url: URL) { + UIApplication.shared.open(url) } } diff --git a/Projects/Detail/Sources/Model/Asset.swift b/Projects/Detail/Sources/Model/Asset.swift new file mode 100644 index 0000000..e1314a9 --- /dev/null +++ b/Projects/Detail/Sources/Model/Asset.swift @@ -0,0 +1,23 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +struct Asset: Sendable, Equatable { + let id: Int + let name: String + let symbol: String + let priceUsd: Double +} + +extension Asset: Codable { + enum CodingKeys: String, CodingKey { + case id, name, symbol + case priceUsd = "price_usd" + } +} diff --git a/Projects/Detail/Sources/Model/DetailViewState.swift b/Projects/Detail/Sources/Model/DetailViewState.swift new file mode 100644 index 0000000..9d2d3d9 --- /dev/null +++ b/Projects/Detail/Sources/Model/DetailViewState.swift @@ -0,0 +1,18 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +enum DetailViewState: Equatable { + case loading + case loaded(ExchangeDetailModel) + case loadingAssets + case loadedAssets + case error(String) + case errorLoadAssets(title: String, message: String, code: Int) +} diff --git a/Projects/Detail/Sources/Model/ExchangeAssetsResponse.swift b/Projects/Detail/Sources/Model/ExchangeAssetsResponse.swift new file mode 100644 index 0000000..49d0a96 --- /dev/null +++ b/Projects/Detail/Sources/Model/ExchangeAssetsResponse.swift @@ -0,0 +1,41 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import HomeInterfaces + +struct ExchangeAssetsResponse: Codable, Equatable { + let status: Status + let data: [AssetResponse] +} + +struct AssetResponse: Codable, Equatable { + let walletAddress: String + let balance: Double + let currency: Currency + + enum CodingKeys: String, CodingKey { + case walletAddress = "wallet_address" + case balance + case currency + } +} + +struct Currency: Codable, Equatable { + let cryptoId: Int + let priceUsd: Double + let symbol: String + let name: String + + enum CodingKeys: String, CodingKey { + case cryptoId = "crypto_id" + case priceUsd = "price_usd" + case symbol + case name + } +} diff --git a/Projects/Detail/Sources/Model/ExchangeDetailModel.swift b/Projects/Detail/Sources/Model/ExchangeDetailModel.swift new file mode 100644 index 0000000..75bcd82 --- /dev/null +++ b/Projects/Detail/Sources/Model/ExchangeDetailModel.swift @@ -0,0 +1,40 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import HomeInterfaces + +struct ExchangeDetailModel: Equatable { + let id: Int + let name: String + let description: String + let logoUrl: String + let spotVolumeUsd: Double? + let makerFee: Double + let takerFee: Double + let dateLaunched: String + let websiteUrl: String? + let twitterUrl: String? +} + +extension ExchangeDetailModel { + init(from exchangeDetail: Exchange) { + self.init( + id: exchangeDetail.id, + name: exchangeDetail.name, + description: exchangeDetail.description ?? "No description available", + logoUrl: exchangeDetail.logo, + spotVolumeUsd: exchangeDetail.spotVolumeUsd, + makerFee: exchangeDetail.makerFee, + takerFee: exchangeDetail.takerFee, + dateLaunched: exchangeDetail.dateLaunched, + websiteUrl: exchangeDetail.websiteUrl, + twitterUrl: exchangeDetail.twitterUrl + ) + } +} diff --git a/Projects/Detail/Sources/Protocols/DetailServiceProtocol.swift b/Projects/Detail/Sources/Protocols/DetailServiceProtocol.swift new file mode 100644 index 0000000..338b427 --- /dev/null +++ b/Projects/Detail/Sources/Protocols/DetailServiceProtocol.swift @@ -0,0 +1,13 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +protocol DetailServiceProtocol: AnyObject, Sendable { + func fetchExchangeAssets(id: Int) async throws -> [Asset] +} diff --git a/Projects/Detail/Sources/Protocols/DetailViewModelCoordinatorDelegate.swift b/Projects/Detail/Sources/Protocols/DetailViewModelCoordinatorDelegate.swift new file mode 100644 index 0000000..58c7615 --- /dev/null +++ b/Projects/Detail/Sources/Protocols/DetailViewModelCoordinatorDelegate.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +protocol DetailViewModelCoordinatorDelegate: AnyObject { + func didRequestOpenURL(_ url: URL) +} diff --git a/Projects/Detail/Sources/Protocols/DetailViewModelDelegate.swift b/Projects/Detail/Sources/Protocols/DetailViewModelDelegate.swift new file mode 100644 index 0000000..5b49094 --- /dev/null +++ b/Projects/Detail/Sources/Protocols/DetailViewModelDelegate.swift @@ -0,0 +1,14 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +protocol DetailViewModelDelegate: AnyObject { + func didUpdateState(_ state: DetailViewState) +} diff --git a/Projects/Detail/Sources/Protocols/DetailViewModelProtocol.swift b/Projects/Detail/Sources/Protocols/DetailViewModelProtocol.swift new file mode 100644 index 0000000..3380ef8 --- /dev/null +++ b/Projects/Detail/Sources/Protocols/DetailViewModelProtocol.swift @@ -0,0 +1,21 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation + +@MainActor +protocol DetailViewModelProtocol: AnyObject { + var assets: [Asset] { get } + var delegate: DetailViewModelDelegate? { get set } + var state: DetailViewState { get } + + func loadData() + func didTapRetry() + func didTapWebsite() + func didTapTwitter() +} diff --git a/Projects/Detail/Sources/Service/DetailEndpoint.swift b/Projects/Detail/Sources/Service/DetailEndpoint.swift new file mode 100644 index 0000000..39627c8 --- /dev/null +++ b/Projects/Detail/Sources/Service/DetailEndpoint.swift @@ -0,0 +1,35 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import NetworkingInterfaces +import Foundation + +enum DetailEndpoint: APIEndpointProtocol { + case fetchAssets(id: Int) + + var baseURL: String { + ProcessInfo.processInfo.environment["CM_API_BASE_URL"] ?? "" + } + + var path: String { + switch self { + case let .fetchAssets(id): + return "/v1/exchange/assets?id=\(id)" + } + } + + var method: NetworkingInterfaces.HTTPMethod { + .get + } + + var headers: [String: String]? { + [ + "X-CMC_PRO_API_KEY": ProcessInfo.processInfo.environment["CM_API_KEY"] ?? "" + ] + } +} diff --git a/Projects/Detail/Sources/Service/DetailService.swift b/Projects/Detail/Sources/Service/DetailService.swift new file mode 100644 index 0000000..76de45e --- /dev/null +++ b/Projects/Detail/Sources/Service/DetailService.swift @@ -0,0 +1,58 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import HomeInterfaces +import NetworkingInterfaces + +enum DetailServiceError: Error, Equatable { + case decodeFail(String?) + case network(Status) +} + +final class DetailService: Sendable { + private nonisolated(unsafe) let networkService: NetworkServiceProtocol + + init(networkService: NetworkServiceProtocol) { + self.networkService = networkService + } + + private func performRequest(endpoint: APIEndpointProtocol) async throws -> T { + let (data, httpUrlResponse) = try await networkService.request(endpoint: endpoint) + + switch httpUrlResponse.statusCode { + case 200...299: + return try decodeResponse(data) + default: + let error: Status = try decodeResponse(data) + throw DetailServiceError.network(error) + } + } + + private func decodeResponse(_ data: Data) throws -> T { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } +} + +extension DetailService: DetailServiceProtocol { + func fetchExchangeAssets(id: Int) async throws -> [Asset] { + let endpoint = DetailEndpoint.fetchAssets(id: id) + + let response: ExchangeAssetsResponse = try await performRequest(endpoint: endpoint) + + return response + .data + .map { asset in + Asset(id: asset.currency.cryptoId, + name: asset.currency.name, + symbol: asset.currency.symbol, + priceUsd: asset.currency.priceUsd) + } + } +} diff --git a/Projects/Detail/Sources/View/AssetTableViewCell.swift b/Projects/Detail/Sources/View/AssetTableViewCell.swift new file mode 100644 index 0000000..cf1103b --- /dev/null +++ b/Projects/Detail/Sources/View/AssetTableViewCell.swift @@ -0,0 +1,136 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit +import DesignSystem + +final class AssetTableViewCell: UITableViewCell { + static let reuseIdentifier = "AssetTableViewCell" + + private lazy var containerView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .secondarySystemGroupedBackground + view.layer.cornerRadius = DSSpacings.medium.rawValue + view.clipsToBounds = true + return view + }() + + private lazy var iconImageView: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFit + imageView.clipsToBounds = true + imageView.tintColor = .systemGray3 + imageView.image = UIImage(systemName: "bitcoinsign.circle.fill") + return imageView + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 17, weight: .regular) + label.textColor = .label + return label + }() + + private lazy var priceLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 13, weight: .regular) + label.textColor = .systemGreen + return label + }() + + private lazy var textStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [nameLabel, priceLabel]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.spacing = DSSpacings.xSmall.rawValue + return stackView + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configure(with asset: Asset) { + nameLabel.text = asset.name + priceLabel.text = formatPrice(asset.priceUsd) + } + + private func formatPrice(_ value: Double) -> String { + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.currencySymbol = "$ " + formatter.maximumFractionDigits = 2 + formatter.minimumFractionDigits = 2 + formatter.groupingSeparator = "." + formatter.decimalSeparator = "," + return formatter.string(from: NSNumber(value: value)) ?? "$ 0,00" + } +} + +extension AssetTableViewCell: ViewCode { + func buildViewHierarch() { + contentView.addSubview(containerView) + containerView.addSubview(iconImageView) + containerView.addSubview(textStackView) + } + + func setUpConstraints() { + let horizontalPadding = DSSpacings.large.rawValue + let verticalPadding = DSSpacings.small.rawValue + + NSLayoutConstraint.activate([ + containerView.topAnchor.constraint(greaterThanOrEqualTo: contentView.topAnchor, + constant: verticalPadding), + containerView.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, + constant: -verticalPadding), + containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, + constant: horizontalPadding), + containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, + constant: -horizontalPadding), + containerView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + + iconImageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: horizontalPadding), + iconImageView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), + iconImageView.widthAnchor.constraint(equalToConstant: 42), + iconImageView.heightAnchor.constraint(equalToConstant: 42), + + textStackView.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, + constant: horizontalPadding), + textStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -horizontalPadding), + textStackView.topAnchor.constraint(equalTo: containerView.topAnchor, + constant: DSSpacings.small.rawValue), + textStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, + constant: -DSSpacings.medium.rawValue) + ]) + } + + func additionalConfiguration() { + selectionStyle = .none + contentView.backgroundColor = .clear + } +} + +#if DEBUG +import SwiftUI + +@available(iOS 17.0, *) +#Preview { + let view = AssetTableViewCell() + view.configure(with: .init(id: 1, name: "opa", symbol: "OPa", priceUsd: 123.4)) + return view +} +#endif diff --git a/Projects/Detail/Sources/View/DetailHeaderView.swift b/Projects/Detail/Sources/View/DetailHeaderView.swift new file mode 100644 index 0000000..98ebb49 --- /dev/null +++ b/Projects/Detail/Sources/View/DetailHeaderView.swift @@ -0,0 +1,236 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit +import DesignSystem + +final class DetailHeaderView: UIView { + private lazy var containerView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .secondarySystemGroupedBackground + view.layer.cornerRadius = DSSpacings.large.rawValue + view.clipsToBounds = true + return view + }() + + private lazy var logoImageView: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFill + imageView.layer.cornerRadius = 11 + imageView.clipsToBounds = true + imageView.tintColor = .systemGray3 + imageView.image = UIImage(systemName: "bahtsign.bank.building.fill") + return imageView + }() + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 16, weight: .semibold) + label.textColor = .label + return label + }() + + private lazy var descriptionLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 11, weight: .regular) + label.textColor = .secondaryLabel + label.numberOfLines = 10 + label.setContentCompressionResistancePriority(.defaultLow, for: .vertical) + return label + }() + + private lazy var topSeparator: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .systemFill + return view + }() + + private lazy var dateLaunchedLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 11, weight: .regular) + label.textColor = .secondaryLabel + return label + }() + + private lazy var makerFeeLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 11, weight: .regular) + label.textColor = .secondaryLabel + label.textAlignment = .left + return label + }() + + private lazy var takerFeeLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 11, weight: .regular) + label.textColor = .secondaryLabel + label.textAlignment = .left + return label + }() + + private lazy var infoStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [dateLaunchedLabel, makerFeeLabel, takerFeeLabel]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.spacing = DSSpacings.xSmall.rawValue + return stackView + }() + + private lazy var bottomSeparator: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .systemFill + return view + }() + + lazy var twitterButton: UIButton = { + let button = UIButton(type: .system) + button.translatesAutoresizingMaskIntoConstraints = false + let config = UIImage.SymbolConfiguration(pointSize: 18) + button.setImage(UIImage(systemName: "bird.fill", withConfiguration: config), for: .normal) + button.tintColor = .white + button.backgroundColor = .systemBlue + button.layer.cornerRadius = 18 + button.clipsToBounds = true + return button + }() + + lazy var websiteButton: UIButton = { + let button = UIButton(type: .system) + button.translatesAutoresizingMaskIntoConstraints = false + let config = UIImage.SymbolConfiguration(pointSize: 18) + button.setImage(UIImage(systemName: "globe", withConfiguration: config), for: .normal) + button.tintColor = .white + button.backgroundColor = .systemBlue + button.layer.cornerRadius = 18 + button.clipsToBounds = true + return button + }() + + private lazy var buttonsStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [twitterButton, websiteButton]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.spacing = DSSpacings.large.rawValue + return stackView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configure(with model: ExchangeDetailModel) { + titleLabel.text = "\(model.name) - ID \(model.id)" + descriptionLabel.text = model.description + dateLaunchedLabel.text = "Date launched: \(model.dateLaunched)" + makerFeeLabel.text = "Maker: \(formatPercentage(model.makerFee))" + takerFeeLabel.text = "Taker: \(formatPercentage(model.takerFee))" + loadImage(from: model.logoUrl) + websiteButton.isHidden = model.websiteUrl == nil + twitterButton.isHidden = model.twitterUrl == nil + } + + private func formatPercentage(_ value: Double) -> String { + String(format: "%.2f%%", value) + } + + private func loadImage(from urlString: String) { + guard let url = URL(string: urlString) else { return } + Task { + do { + let (data, _) = try await URLSession.shared.data(from: url) + if let image = UIImage(data: data) { + await MainActor.run { logoImageView.image = image } + } + } catch {} + } + } +} + +extension DetailHeaderView: ViewCode { + func buildViewHierarch() { + addSubview(containerView) + containerView.addSubview(logoImageView) + containerView.addSubview(titleLabel) + containerView.addSubview(descriptionLabel) + containerView.addSubview(topSeparator) + containerView.addSubview(infoStackView) + containerView.addSubview(bottomSeparator) + containerView.addSubview(buttonsStackView) + } + + func setUpConstraints() { + let padding = DSSpacings.large.rawValue + let innerPadding = DSSpacings.medium.rawValue + + NSLayoutConstraint.activate([ + containerView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor), + containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding), + containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding), + containerView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor), + containerView.centerYAnchor.constraint(equalTo: centerYAnchor), + + logoImageView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: padding), + logoImageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: padding), + logoImageView.widthAnchor.constraint(equalToConstant: 64), + logoImageView.heightAnchor.constraint(equalToConstant: 64), + + titleLabel.topAnchor.constraint(equalTo: logoImageView.bottomAnchor, constant: innerPadding), + titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: padding), + titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -padding), + + descriptionLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, + constant: DSSpacings.small.rawValue), + descriptionLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: padding), + descriptionLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -padding), + + topSeparator.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, + constant: innerPadding), + topSeparator.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, + constant: DSSpacings.xLarge.rawValue), + topSeparator.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, + constant: -DSSpacings.xLarge.rawValue), + topSeparator.heightAnchor.constraint(equalToConstant: 3.0 / UIScreen.main.scale), + + infoStackView.topAnchor.constraint(equalTo: topSeparator.bottomAnchor, constant: innerPadding), + infoStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: padding), + infoStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -padding), + + bottomSeparator.topAnchor.constraint(equalTo: infoStackView.bottomAnchor, + constant: innerPadding), + bottomSeparator.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, + constant: DSSpacings.xLarge.rawValue), + bottomSeparator.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, + constant: -DSSpacings.xLarge.rawValue), + bottomSeparator.heightAnchor.constraint(equalToConstant: 3.0 / UIScreen.main.scale), + + twitterButton.widthAnchor.constraint(equalToConstant: 36), + twitterButton.heightAnchor.constraint(equalToConstant: 36), + websiteButton.widthAnchor.constraint(equalToConstant: 36), + websiteButton.heightAnchor.constraint(equalToConstant: 36), + + buttonsStackView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor), + buttonsStackView.topAnchor.constraint(equalTo: bottomSeparator.bottomAnchor, + constant: padding), + buttonsStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -padding) + ]) + } +} diff --git a/Projects/Detail/Sources/View/DetailViewController.swift b/Projects/Detail/Sources/View/DetailViewController.swift new file mode 100644 index 0000000..885fab8 --- /dev/null +++ b/Projects/Detail/Sources/View/DetailViewController.swift @@ -0,0 +1,211 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit +import DesignSystem + +@MainActor +final class DetailViewController: UIViewController { + + private enum Section: Int, CaseIterable { + case assets = 0 + } + + private let viewModel: DetailViewModelProtocol + private var detailModel: ExchangeDetailModel? + + private lazy var tableView: UITableView = { + let tableView = UITableView(frame: .zero, style: .plain) + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.register(AssetTableViewCell.self, forCellReuseIdentifier: AssetTableViewCell.reuseIdentifier) + tableView.delegate = self + tableView.dataSource = self + tableView.separatorStyle = .none + tableView.isHidden = true + return tableView + }() + + private lazy var headerView: DetailHeaderView = { + let view = DetailHeaderView() + return view + }() + + private lazy var loadingIndicator: UIActivityIndicatorView = { + let indicator = UIActivityIndicatorView(style: .large) + indicator.translatesAutoresizingMaskIntoConstraints = false + indicator.hidesWhenStopped = true + return indicator + }() + + private lazy var errorView: ErrorView = { + let view = ErrorView() + view.translatesAutoresizingMaskIntoConstraints = false + view.isHidden = true + return view + }() + + init(viewModel: DetailViewModelProtocol) { + self.viewModel = viewModel + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + viewModel.delegate = self + viewModel.loadData() + } + + private func updateTableHeaderView() { + headerView.frame.size.width = tableView.bounds.width + + let targetSize = CGSize(width: tableView.bounds.width, height: UIView.layoutFittingCompressedSize.height) + let dynamicSize = headerView.systemLayoutSizeFitting( + targetSize, + withHorizontalFittingPriority: .required, + verticalFittingPriority: .fittingSizeLevel + ) + + if headerView.frame.height != dynamicSize.height { + headerView.frame.size.height = dynamicSize.height + tableView.tableHeaderView = headerView + } + } + + @objc private func didTapWebsiteButton() { + viewModel.didTapWebsite() + } + + @objc private func didTapTwitterButton() { + viewModel.didTapTwitter() + } +} + +extension DetailViewController: UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + if case .loadedAssets = viewModel.state, viewModel.assets.isEmpty { + return 0 + } + + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + viewModel.assets.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell( + withIdentifier: AssetTableViewCell.reuseIdentifier, + for: indexPath + ) as? AssetTableViewCell else { + return UITableViewCell() + } + + cell.configure(with: viewModel.assets[indexPath.row]) + return cell + } +} + +extension DetailViewController: ViewCode { + func buildViewHierarch() { + view.addSubview(tableView) + view.addSubview(loadingIndicator) + view.addSubview(errorView) + } + + func setUpConstraints() { + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), + loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor), + + errorView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + errorView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + errorView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + errorView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + + func additionalConfiguration() { + view.backgroundColor = .systemBackground + + headerView.websiteButton.addTarget(self, action: #selector(didTapWebsiteButton), for: .touchUpInside) + headerView.twitterButton.addTarget(self, action: #selector(didTapTwitterButton), for: .touchUpInside) + errorView.retryAction = { [weak self] in + self?.viewModel.didTapRetry() + } + } +} + +extension DetailViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let headerView = HeaderSectionView() + + headerView.configure(title: "Assets") + headerView.loader.startAnimating() + + if case .loadedAssets = viewModel.state { + headerView.loader.stopAnimating() + headerView.loader.isHidden = true + } + + return headerView + } +} + +extension DetailViewController: DetailViewModelDelegate { + func didUpdateState(_ state: DetailViewState) { + switch state { + case .loading: + tableView.isHidden = true + errorView.isHidden = true + loadingIndicator.startAnimating() + + case .loaded(let model): + loadingIndicator.stopAnimating() + errorView.isHidden = true + tableView.isHidden = false + detailModel = model + title = model.name + headerView.configure(with: model) + updateTableHeaderView() + + case .loadingAssets: + return + case .loadedAssets: + if viewModel.assets.isEmpty { + tableView.reloadData() + return + } + let indexSet = IndexSet(integer: Section.assets.rawValue) + tableView.reloadSections(indexSet, with: .fade) + + case .error(let message): + loadingIndicator.stopAnimating() + tableView.isHidden = true + errorView.isHidden = false + errorView.configure(title: "Error Loading Details", message: message) + + case .errorLoadAssets(let title, let message, _): + errorView.isHidden = false + errorView.configure(title: title, message: message) + errorView.retryAction = { [weak self] in + self?.viewModel.didTapRetry() + } + } + } +} diff --git a/Projects/Detail/Sources/View/HeaderSectionView.swift b/Projects/Detail/Sources/View/HeaderSectionView.swift new file mode 100644 index 0000000..7f80a0d --- /dev/null +++ b/Projects/Detail/Sources/View/HeaderSectionView.swift @@ -0,0 +1,77 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit +import DesignSystem + +final class HeaderSectionView: UITableViewHeaderFooterView { + // MARK: - UI Components + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .systemFont(ofSize: 20, weight: .semibold) + label.textColor = .label + return label + }() + + lazy var loader: UIActivityIndicatorView = { + let indicator = UIActivityIndicatorView(style: .medium) + indicator.translatesAutoresizingMaskIntoConstraints = false + indicator.hidesWhenStopped = true + return indicator + }() + + private lazy var stackView: UIStackView = { + let stack = UIStackView(arrangedSubviews: [titleLabel, loader]) + stack.translatesAutoresizingMaskIntoConstraints = false + stack.axis = .horizontal + stack.spacing = 8 + stack.alignment = .center + return stack + }() + + // MARK: - Init + + override init(reuseIdentifier: String?) { + super.init(reuseIdentifier: reuseIdentifier) + setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Configuration + + func configure(title: String) { + titleLabel.text = title + } +} + +// MARK: - ViewCode Extension + +extension HeaderSectionView: ViewCode { + func buildViewHierarch() { + contentView.addSubview(stackView) + } + + func setUpConstraints() { + NSLayoutConstraint.activate([ + stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, + constant: DSSpacings.large.rawValue), + stackView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + stackView.trailingAnchor.constraint(lessThanOrEqualTo: contentView.trailingAnchor, + constant: -DSSpacings.large.rawValue), + stackView.topAnchor.constraint(equalTo: contentView.topAnchor, + constant: DSSpacings.medium.rawValue), + stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, + constant: -DSSpacings.medium.rawValue) + ]) + } +} diff --git a/Projects/Detail/Sources/ViewModel/DetailViewModel.swift b/Projects/Detail/Sources/ViewModel/DetailViewModel.swift new file mode 100644 index 0000000..7fb2061 --- /dev/null +++ b/Projects/Detail/Sources/ViewModel/DetailViewModel.swift @@ -0,0 +1,79 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import HomeInterfaces + +@MainActor +final class DetailViewModel: DetailViewModelProtocol { + weak var delegate: DetailViewModelDelegate? + weak var coordinatorDelegate: DetailViewModelCoordinatorDelegate? + + private let service: DetailServiceProtocol + private var exchangeId: Int? + private var exchange: Exchange? + private(set) var assets: [Asset] = [] + private var detail: ExchangeDetailModel? + + private(set) var state: DetailViewState = .loading { + didSet { delegate?.didUpdateState(state) } + } + + init(service: DetailServiceProtocol) { + self.service = service + } + + func configure(with exchangeId: Int) { + self.exchangeId = exchangeId + } + + func configure(with exchange: Exchange) { + self.exchange = exchange + } + + func loadData() { + if let exchange { + let model = ExchangeDetailModel(from: exchange) + self.detail = model + state = .loaded(model) + + Task { + do { + let assets = try await service.fetchExchangeAssets(id: exchange.id) + self.assets = assets + state = .loadedAssets + } catch { + state = .errorLoadAssets( + title: "Failed to load assets", + message: error.localizedDescription, + code: 0 + ) + } + } + return + } + + state = .error("Invalid Exchanges, please try another option") + } + + func didTapRetry() { + loadData() + } + + func didTapWebsite() { + guard let urlString = detail?.websiteUrl, + let url = URL(string: urlString) else { return } + coordinatorDelegate?.didRequestOpenURL(url) + } + + func didTapTwitter() { + guard let urlString = detail?.twitterUrl, + let url = URL(string: urlString) else { return } + coordinatorDelegate?.didRequestOpenURL(url) + } +} diff --git a/Projects/Detail/Tests/Coordinator/DetailCoordinatorTests.swift b/Projects/Detail/Tests/Coordinator/DetailCoordinatorTests.swift new file mode 100644 index 0000000..68ce71e --- /dev/null +++ b/Projects/Detail/Tests/Coordinator/DetailCoordinatorTests.swift @@ -0,0 +1,111 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import DependencyInjectionInterfaces +import DependencyInjectionTesting +import HomeInterfaces +import NavigationInterfaces +import NavigationTesting +import NetworkingInterfaces +import Testing +import UIKit + +@testable import Detail + +@MainActor +@Suite +struct DetailCoordinatorTests { + + // MARK: - Start Tests + + @Test("GIVEN DetailCoordinator with exchange WHEN start is called THEN pushes detail view controller") + func startWithExchangePushesDetailViewController() { + let (sut, doubles) = makeSut(exchange: makeExchange()) + doubles.injectorSpy + .register(NetworkServiceProtocol.self) { _ in + doubles.networkSpy + } + + sut.start() + + #expect(doubles.injectorSpy.calledMethods == [.resolve]) + #expect(doubles.navigationController.calledMethods == [.pushViewController]) + } + + @Test("GIVEN DetailCoordinator with exchangeId WHEN start is called THEN pushes detail view controller") + func startWithExchangeIdPushesDetailViewController() { + let (sut, doubles) = makeSut(exchangeId: 1) + doubles.injectorSpy + .register(NetworkServiceProtocol.self) { _ in + doubles.networkSpy + } + + sut.start() + + #expect(doubles.injectorSpy.calledMethods == [.resolve]) + #expect(doubles.navigationController.calledMethods == [.pushViewController]) + } +} + +extension DetailCoordinatorTests { + typealias SutAndDoubles = ( + sut: DetailCoordinator, + doubles: ( + networkSpy: NetworkServiceProtocolSpy, + coordinatorSpy: CoordinatorSpy, + navigationController: NavigationControllerSpy, + injectorSpy: DependencyInjectorSpy + ) + ) + + func makeSut( + exchange: Exchange? = nil, + exchangeId: Int = 0 + ) -> SutAndDoubles { + + let navigationController = NavigationControllerSpy() + let coordinatorSpy = CoordinatorSpy(navigationController: navigationController) + let networkSpy = NetworkServiceProtocolSpy() + let injectorSpy = DependencyInjectorSpy() + SharedContainer.shared.setInjector(injectorSpy) + + + let sut: DetailCoordinator + + if let exchange = exchange { + sut = DetailCoordinator( + parentCoordinator: coordinatorSpy, + navigationController: navigationController, + exchange: exchange + ) + } else { + sut = DetailCoordinator( + parentCoordinator: coordinatorSpy, + navigationController: navigationController, + exchangeId: exchangeId + ) + } + + return (sut, (networkSpy, coordinatorSpy, navigationController, injectorSpy)) + } + + func makeExchange() -> Exchange { + Exchange( + id: 1, + name: "Binance", + description: "Binance Exchange", + logo: "https://logo.url", + spotVolumeUsd: 1000000.0, + makerFee: 0.1, + takerFee: 0.2, + dateLaunched: "2017-07-14", + websiteUrl: "https://binance.com", + twitterUrl: "https://twitter.com/binance" + ) + } +} diff --git a/Projects/Detail/Tests/Doubles/DetailServiceProtocolSpy.swift b/Projects/Detail/Tests/Doubles/DetailServiceProtocolSpy.swift new file mode 100644 index 0000000..93958c2 --- /dev/null +++ b/Projects/Detail/Tests/Doubles/DetailServiceProtocolSpy.swift @@ -0,0 +1,32 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Detail + +@MainActor +final class DetailServiceProtocolSpy: DetailServiceProtocol, Sendable { + enum Method: Equatable { + case fetchExchangeAssets + } + + var calledMethods: [Method] = [] + nonisolated(unsafe) var fetchExchangeAssetsResult: Result<[Asset], Error>? + + nonisolated func fetchExchangeAssets(id: Int) async throws -> [Asset] { + await MainActor.run { + calledMethods.append(.fetchExchangeAssets) + } + + guard let result = fetchExchangeAssetsResult else { + fatalError("fetchExchangeAssetsResult not set") + } + + return try result.get() + } +} diff --git a/Projects/Detail/Tests/Doubles/DetailViewModelSpy.swift b/Projects/Detail/Tests/Doubles/DetailViewModelSpy.swift new file mode 100644 index 0000000..382b6bf --- /dev/null +++ b/Projects/Detail/Tests/Doubles/DetailViewModelSpy.swift @@ -0,0 +1,38 @@ +import Foundation +@testable import Detail + +@MainActor +final class DetailViewModelSpy: DetailViewModelProtocol { + // MARK: - Properties + + weak var delegate: DetailViewModelDelegate? + var assets: [Asset] = [] + var state: DetailViewState = .loading + + public enum Method { + case loadData + case didTapRetry + case didTapWebsite + case didTapTwitter + } + + public var calledMethods: [Method] = [] + + // MARK: - Methods + + func loadData() { + calledMethods.append(.loadData) + } + + func didTapRetry() { + calledMethods.append(.didTapRetry) + } + + func didTapWebsite() { + calledMethods.append(.didTapWebsite) + } + + func didTapTwitter() { + calledMethods.append(.didTapTwitter) + } +} diff --git a/Projects/Detail/Tests/Doubles/NetworkServiceProtocolSpy.swift b/Projects/Detail/Tests/Doubles/NetworkServiceProtocolSpy.swift new file mode 100644 index 0000000..da4fd58 --- /dev/null +++ b/Projects/Detail/Tests/Doubles/NetworkServiceProtocolSpy.swift @@ -0,0 +1,29 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import NetworkingInterfaces + +final class NetworkServiceProtocolSpy: NetworkServiceProtocol, @unchecked Sendable { + enum Method: Equatable { + case request + } + + var calledMethods: [Method] = [] + var requestResult: Result<(Data, HTTPURLResponse), Error>? + + func request(endpoint: APIEndpointProtocol) async throws -> (Data, HTTPURLResponse) { + calledMethods.append(.request) + + guard let result = requestResult else { + fatalError("requestResult not set") + } + + return try result.get() + } +} diff --git a/Projects/Detail/Tests/PlaceHolder.swift b/Projects/Detail/Tests/PlaceHolder.swift deleted file mode 100644 index e69de29..0000000 diff --git a/Projects/Detail/Tests/Service/DetailEndpointTests.swift b/Projects/Detail/Tests/Service/DetailEndpointTests.swift new file mode 100644 index 0000000..8734ec6 --- /dev/null +++ b/Projects/Detail/Tests/Service/DetailEndpointTests.swift @@ -0,0 +1,55 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import Foundation +import NetworkingInterfaces +@testable import Detail + +struct DetailEndpointTests { + + @Test("GIVEN fetchAssets endpoint WHEN accessing path THEN returns correct path with ID parameter") + func testFetchAssetsPath() throws { + let id = 1 + let endpoint = DetailEndpoint.fetchAssets(id: id) + + #expect(endpoint.path == "/v1/exchange/assets?id=1") + } + + @Test("GIVEN fetchAssets endpoint with different ID WHEN accessing path THEN returns correct path") + func testFetchAssetsPathWithDifferentId() throws { + let id = 270 + let endpoint = DetailEndpoint.fetchAssets(id: id) + + #expect(endpoint.path == "/v1/exchange/assets?id=270") + } + + @Test("GIVEN fetchAssets endpoint WHEN accessing method THEN returns GET method") + func testFetchAssetsMethod() throws { + let endpoint = DetailEndpoint.fetchAssets(id: 1) + let method = endpoint.method + + #expect(method == .get) + } + + @Test("GIVEN any endpoint WHEN accessing headers THEN contains API key header") + func testEndpointHeaders() throws { + let endpoint = DetailEndpoint.fetchAssets(id: 1) + let headers = endpoint.headers + + #expect(headers?["X-CMC_PRO_API_KEY"] != nil) + } + + @Test("GIVEN any endpoint WHEN accessing baseURL THEN returns environment variable value") + func testEndpointBaseURL() throws { + let endpoint = DetailEndpoint.fetchAssets(id: 1) + let baseURL = endpoint.baseURL + + #expect(!baseURL.isEmpty || ProcessInfo.processInfo.environment["CM_API_BASE_URL"] == nil) + } +} diff --git a/Projects/Detail/Tests/Service/DetailServiceTests.swift b/Projects/Detail/Tests/Service/DetailServiceTests.swift new file mode 100644 index 0000000..1a16e8b --- /dev/null +++ b/Projects/Detail/Tests/Service/DetailServiceTests.swift @@ -0,0 +1,146 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +import HomeInterfaces +import Testing + +@testable import Detail + +struct DetailServiceTests { + @Test("GIVEN successful response WHEN fetchExchangeAssets is called THEN returns mapped assets") + func testFetchExchangeAssetsSuccess() async throws { + let (sut, networkSpy) = makeSut() + let mockResponse = """ + { + "status": { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": null, + "error_message": null, + "elapsed": 10, + "credit_count": 1 + }, + "data": [ + { + "wallet_address": "0x123", + "balance": 100.0, + "currency": { + "crypto_id": 1, + "price_usd": 50000.0, + "symbol": "BTC", + "name": "Bitcoin" + } + }, + { + "wallet_address": "0x456", + "balance": 200.0, + "currency": { + "crypto_id": 2, + "price_usd": 3000.0, + "symbol": "ETH", + "name": "Ethereum" + } + } + ] + } + """ + let data = try #require(mockResponse.data(using: .utf8)) + let url = try #require(URL(string: "https://api.example.com")) + let httpResponse = try #require(HTTPURLResponse( + url: url, + statusCode: 200, + httpVersion: nil, + headerFields: nil + )) + + networkSpy.requestResult = .success((data, httpResponse)) + + let result = try await sut.fetchExchangeAssets(id: 1) + + #expect(networkSpy.calledMethods == [.request]) + #expect(result.count == 2) + #expect(result[0] == Asset(id: 1, name: "Bitcoin", symbol: "BTC", priceUsd: 50000.0)) + #expect(result[1] == Asset(id: 2, name: "Ethereum", symbol: "ETH", priceUsd: 3000.0)) + } + + @Test("GIVEN error response WHEN fetchExchangeAssets is called THEN throws network error") + func testFetchExchangeAssetsNetworkError() async throws { + let (sut, networkSpy) = makeSut() + let mockResponse = """ + { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": 404, + "error_message": "Exchange not found", + "elapsed": 10, + "credit_count": 1 + } + """ + let data = try #require(mockResponse.data(using: .utf8)) + let url = try #require(URL(string: "https://api.example.com")) + let httpResponse = try #require(HTTPURLResponse( + url: url, + statusCode: 404, + httpVersion: nil, + headerFields: nil + )) + + networkSpy.requestResult = .success((data, httpResponse)) + + do { + _ = try await sut.fetchExchangeAssets(id: 999) + Issue.record("Expected error to be thrown") + } catch let error as DetailServiceError { + #expect(error == .network(Status( + timestamp: "2024-01-01T00:00:00.000Z", + errorCode: 404, + errorMessage: "Exchange not found", + elapsed: 10, + creditCount: 1 + ))) + #expect(networkSpy.calledMethods == [.request]) + } + } + + @Test("GIVEN decode failure WHEN fetchExchangeAssets is called THEN throws error") + func testFetchExchangeAssetsDecodeFail() async throws { + let (sut, networkSpy) = makeSut() + let mockResponse = """ + { "invalid": "json" } + """ + let data = try #require(mockResponse.data(using: .utf8)) + let url = try #require(URL(string: "https://api.example.com")) + let httpResponse = try #require(HTTPURLResponse( + url: url, + statusCode: 200, + httpVersion: nil, + headerFields: nil + )) + + networkSpy.requestResult = .success((data, httpResponse)) + + do { + _ = try await sut.fetchExchangeAssets(id: 1) + Issue.record("Expected error to be thrown") + } catch { + #expect(networkSpy.calledMethods == [.request]) + } + } +} + +extension DetailServiceTests { + typealias SutAndDoubles = ( + sut: DetailService, + networkSpy: NetworkServiceProtocolSpy + ) + + func makeSut() -> SutAndDoubles { + let networkSpy = NetworkServiceProtocolSpy() + let sut = DetailService(networkService: networkSpy) + return (sut, networkSpy) + } +} diff --git a/Projects/Detail/Tests/Service/DetailViewModelCoordinatorDelegateSpy.swift b/Projects/Detail/Tests/Service/DetailViewModelCoordinatorDelegateSpy.swift new file mode 100644 index 0000000..8fae1ae --- /dev/null +++ b/Projects/Detail/Tests/Service/DetailViewModelCoordinatorDelegateSpy.swift @@ -0,0 +1,23 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Detail + +@MainActor +final class DetailViewModelCoordinatorDelegateSpy: DetailViewModelCoordinatorDelegate { + enum Method: Equatable { + case didRequestOpenURL(URL) + } + + var calledMethods: [Method] = [] + + func didRequestOpenURL(_ url: URL) { + calledMethods.append(.didRequestOpenURL(url)) + } +} diff --git a/Projects/Detail/Tests/Service/DetailViewModelDelegateSpy.swift b/Projects/Detail/Tests/Service/DetailViewModelDelegateSpy.swift new file mode 100644 index 0000000..36f7b66 --- /dev/null +++ b/Projects/Detail/Tests/Service/DetailViewModelDelegateSpy.swift @@ -0,0 +1,23 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Foundation +@testable import Detail + +@MainActor +final class DetailViewModelDelegateSpy: DetailViewModelDelegate { + enum Method: Equatable { + case didUpdateState(DetailViewState) + } + + var calledMethods: [Method] = [] + + func didUpdateState(_ state: DetailViewState) { + calledMethods.append(.didUpdateState(state)) + } +} diff --git a/Projects/Detail/Tests/View/DetailViewControllerTests.swift b/Projects/Detail/Tests/View/DetailViewControllerTests.swift new file mode 100644 index 0000000..ebda350 --- /dev/null +++ b/Projects/Detail/Tests/View/DetailViewControllerTests.swift @@ -0,0 +1,157 @@ +import Testing +import Foundation +@testable import Detail + +@MainActor +struct DetailViewControllerTests { + + // MARK: - viewDidLoad + + @Test("GIVEN DetailViewController WHEN viewDidLoad is called THEN calls loadData on viewModel") + func testViewDidLoadCallsLoadData() { + let (sut, viewModelSpy) = makeSut() + + sut.loadViewIfNeeded() + + #expect(viewModelSpy.calledMethods == [.loadData]) + } + + @Test("GIVEN DetailViewController WHEN viewDidLoad is called THEN sets delegate on viewModel") + func testViewDidLoadSetsDelegate() { + let (sut, viewModelSpy) = makeSut() + + sut.loadViewIfNeeded() + + #expect(viewModelSpy.delegate != nil) + } + + // MARK: - didUpdateState + + @Test("GIVEN DetailViewController WHEN didUpdateState with loading THEN hides tableView and shows loading indicator") + func testDidUpdateStateWithLoading() { + let (sut, _) = makeSut() + sut.loadViewIfNeeded() + + sut.didUpdateState(.loading) + + #expect(true) + } + + @Test("GIVEN DetailViewController WHEN didUpdateState with loaded THEN shows tableView and sets title") + func testDidUpdateStateWithLoaded() { + let (sut, _) = makeSut() + sut.loadViewIfNeeded() + let model = makeDetailModel() + + sut.didUpdateState(.loaded(model)) + + #expect(sut.title == model.name) + } + + @Test("GIVEN DetailViewController WHEN didUpdateState with loadingAssets THEN does not crash") + func testDidUpdateStateWithLoadingAssets() { + let (sut, _) = makeSut() + sut.loadViewIfNeeded() + + sut.didUpdateState(.loadingAssets) + + #expect(true) + } + + @Test("GIVEN DetailViewController WHEN didUpdateState with loadedAssets THEN reloads table data") + func testDidUpdateStateWithLoadedAssets() { + let (sut, _) = makeSut() + sut.loadViewIfNeeded() + sut.didUpdateState(.loaded(makeDetailModel())) + + sut.didUpdateState(.loadedAssets) + + #expect(true) + } + + @Test("GIVEN DetailViewController WHEN didUpdateState with error THEN shows error view") + func testDidUpdateStateWithError() { + let (sut, _) = makeSut() + sut.loadViewIfNeeded() + + sut.didUpdateState(.error("Test error")) + + #expect(true) + } + + @Test("GIVEN DetailViewController WHEN didUpdateState with errorLoadAssets THEN shows error view") + func testDidUpdateStateWithErrorLoadAssets() { + let (sut, _) = makeSut() + sut.loadViewIfNeeded() + sut.didUpdateState(.loaded(makeDetailModel())) + + sut.didUpdateState(.errorLoadAssets(title: "Failed to load assets", message: "Server error", code: 0)) + + #expect(true) + } + + // MARK: - Button actions + + @Test("GIVEN DetailViewController WHEN website button is tapped THEN calls didTapWebsite on viewModel") + func testDidTapWebsiteButton() { + let (sut, viewModelSpy) = makeSut() + sut.loadViewIfNeeded() + viewModelSpy.calledMethods.removeAll() + + sut.perform(NSSelectorFromString("didTapWebsiteButton")) + + #expect(viewModelSpy.calledMethods == [.didTapWebsite]) + } + + @Test("GIVEN DetailViewController WHEN twitter button is tapped THEN calls didTapTwitter on viewModel") + func testDidTapTwitterButton() { + let (sut, viewModelSpy) = makeSut() + sut.loadViewIfNeeded() + viewModelSpy.calledMethods.removeAll() + + sut.perform(NSSelectorFromString("didTapTwitterButton")) + + #expect(viewModelSpy.calledMethods == [.didTapTwitter]) + } + + // MARK: - Table view data source + + @Test("GIVEN DetailViewController with loadedAssets and empty assets WHEN numberOfSections is called THEN returns zero") + func testNumberOfSectionsWithEmptyAssets() { + let (sut, viewModelSpy) = makeSut() + sut.loadViewIfNeeded() + viewModelSpy.state = .loadedAssets + viewModelSpy.assets = [] + + sut.didUpdateState(.loaded(makeDetailModel())) + sut.didUpdateState(.loadedAssets) + + #expect(true) + } +} + +extension DetailViewControllerTests { + private func makeSut() -> (viewController: DetailViewController, viewModelSpy: DetailViewModelSpy) { + let viewModelSpy = DetailViewModelSpy() + let viewController = DetailViewController(viewModel: viewModelSpy) + return (viewController, viewModelSpy) + } + + private func makeDetailModel( + websiteUrl: String? = "https://test.com", + twitterUrl: String? = "https://twitter.com/test" + ) -> ExchangeDetailModel { + ExchangeDetailModel( + id: 1, + name: "Test Exchange", + description: "Test Description", + logoUrl: "https://test.com/logo.png", + spotVolumeUsd: 1000000, + makerFee: 0.1, + takerFee: 0.2, + dateLaunched: "2020-01-01", + websiteUrl: websiteUrl, + twitterUrl: twitterUrl + ) + } +} diff --git a/Projects/Detail/Tests/ViewModel/DetailViewModelTests.swift b/Projects/Detail/Tests/ViewModel/DetailViewModelTests.swift new file mode 100644 index 0000000..52446ec --- /dev/null +++ b/Projects/Detail/Tests/ViewModel/DetailViewModelTests.swift @@ -0,0 +1,181 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import Testing +import Foundation +import HomeInterfaces +@testable import Detail + +@MainActor +struct DetailViewModelTests { + + @Test("GIVEN valid exchange WHEN loadData is called THEN fetches assets and updates state to loaded") + func testLoadDataSuccess() async throws { + let (sut, doubles) = makeSut() + let mockAssets = [ + Asset(id: 1, name: "Bitcoin", symbol: "BTC", priceUsd: 50000.0) + ] + doubles.serviceSpy.fetchExchangeAssetsResult = .success(mockAssets) + + sut.configure(with: makeExchange()) + + sut.loadData() + + try await Task.sleep(nanoseconds: 100_000_000) + + let expectedModel = ExchangeDetailModel(from: makeExchange()) + #expect(doubles.serviceSpy.calledMethods == [.fetchExchangeAssets]) + #expect(doubles.delegateSpy.calledMethods == [ + .didUpdateState(.loaded(expectedModel)), + .didUpdateState(.loadedAssets) + ]) + #expect(sut.assets == mockAssets) + } + + @Test("GIVEN no exchange configured WHEN loadData is called THEN updates state to error") + func testLoadDataWithoutConfiguredExchange() async throws { + let (sut, doubles) = makeSut() + + sut.loadData() + + try await Task.sleep(nanoseconds: 100_000_000) + + #expect(doubles.serviceSpy.calledMethods.isEmpty) + #expect(doubles.delegateSpy.calledMethods == [ + .didUpdateState(.error("Invalid Exchanges, please try another option")) + ]) + } + + @Test("GIVEN network error WHEN loadData is called THEN updates state to errorLoadAssets") + func testLoadDataAssetsError() async throws { + let (sut, doubles) = makeSut() + let error = NSError(domain: "test", code: 500, userInfo: [NSLocalizedDescriptionKey: "Server error"]) + doubles.serviceSpy.fetchExchangeAssetsResult = .failure(error) + + sut.configure(with: makeExchange()) + + sut.loadData() + + try await Task.sleep(nanoseconds: 100_000_000) + + let expectedModel = ExchangeDetailModel(from: makeExchange()) + #expect(doubles.serviceSpy.calledMethods == [.fetchExchangeAssets]) + #expect(doubles.delegateSpy.calledMethods == [ + .didUpdateState(.loaded(expectedModel)), + .didUpdateState(.errorLoadAssets( + title: "Failed to load assets", + message: "Server error", + code: 0 + )) + ]) + } + + @Test("GIVEN loaded state with website URL WHEN didTapWebsite is called THEN notifies coordinator") + func testDidTapWebsite() async throws { + let (sut, doubles) = makeSut() + doubles.serviceSpy.fetchExchangeAssetsResult = .success([]) + + sut.configure(with: makeExchange(websiteUrl: "https://binance.com")) + sut.loadData() + try await Task.sleep(nanoseconds: 100_000_000) + + sut.didTapWebsite() + + #expect(doubles.coordinatorDelegateSpy.calledMethods == [ + .didRequestOpenURL(URL(string: "https://binance.com")!) + ]) + } + + @Test("GIVEN loaded state with twitter URL WHEN didTapTwitter is called THEN notifies coordinator") + func testDidTapTwitter() async throws { + let (sut, doubles) = makeSut() + doubles.serviceSpy.fetchExchangeAssetsResult = .success([]) + + sut.configure(with: makeExchange(twitterUrl: "https://twitter.com/binance")) + sut.loadData() + try await Task.sleep(nanoseconds: 100_000_000) + + sut.didTapTwitter() + + #expect(doubles.coordinatorDelegateSpy.calledMethods == [ + .didRequestOpenURL(URL(string: "https://twitter.com/binance")!) + ]) + } + + @Test("GIVEN error state WHEN didTapRetry is called THEN retries loading data") + func testDidTapRetry() async throws { + let (sut, doubles) = makeSut() + let error = NSError(domain: "test", code: 500, userInfo: [NSLocalizedDescriptionKey: "Server error"]) + doubles.serviceSpy.fetchExchangeAssetsResult = .failure(error) + + sut.configure(with: makeExchange()) + sut.loadData() + try await Task.sleep(nanoseconds: 100_000_000) + + let mockAssets = [ + Asset(id: 1, name: "Bitcoin", symbol: "BTC", priceUsd: 50000.0) + ] + doubles.serviceSpy.fetchExchangeAssetsResult = .success(mockAssets) + + sut.didTapRetry() + try await Task.sleep(nanoseconds: 100_000_000) + + #expect(doubles.serviceSpy.calledMethods == [.fetchExchangeAssets, .fetchExchangeAssets]) + #expect(doubles.delegateSpy.calledMethods.last == .didUpdateState(.loadedAssets)) + #expect(sut.assets == mockAssets) + } +} + +extension DetailViewModelTests { + typealias SutAndDoubles = ( + sut: DetailViewModel, + doubles: ( + serviceSpy: DetailServiceProtocolSpy, + delegateSpy: DetailViewModelDelegateSpy, + coordinatorDelegateSpy: DetailViewModelCoordinatorDelegateSpy + ) + ) + + func makeSut() -> SutAndDoubles { + let serviceSpy = DetailServiceProtocolSpy() + let delegateSpy = DetailViewModelDelegateSpy() + let coordinatorDelegateSpy = DetailViewModelCoordinatorDelegateSpy() + + let sut = DetailViewModel(service: serviceSpy) + sut.delegate = delegateSpy + sut.coordinatorDelegate = coordinatorDelegateSpy + + return (sut, (serviceSpy, delegateSpy, coordinatorDelegateSpy)) + } + + func makeExchange( + id: Int = 1, + name: String = "Binance", + description: String? = "Binance Exchange", + logo: String = "https://logo.url", + spotVolumeUsd: Double? = 1000000.0, + makerFee: Double = 0.1, + takerFee: Double = 0.2, + dateLaunched: String = "2017-07-14", + websiteUrl: String? = nil, + twitterUrl: String? = nil + ) -> Exchange { + Exchange( + id: id, + name: name, + description: description, + logo: logo, + spotVolumeUsd: spotVolumeUsd, + makerFee: makerFee, + takerFee: takerFee, + dateLaunched: dateLaunched, + websiteUrl: websiteUrl, + twitterUrl: twitterUrl + ) + } +} diff --git a/Projects/Home/Interfaces/Model/Status.swift b/Projects/Home/Interfaces/Model/Status.swift index 7de661a..eaf5596 100644 --- a/Projects/Home/Interfaces/Model/Status.swift +++ b/Projects/Home/Interfaces/Model/Status.swift @@ -8,7 +8,7 @@ import Foundation -public struct Status: Equatable { +public struct Status: Equatable, Sendable { let timestamp: String let errorCode: Int? let errorMessage: String? From a4636ac399eeb0c8db807c2be836dfb4af29e585 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Mon, 9 Feb 2026 20:11:09 -0300 Subject: [PATCH 13/16] fix: envs adjust (#28) --- .gitignore | 3 ++- Projects/App/Project.swift | 2 +- .../ProjectDescriptionHelpers/Project+Template.swift | 10 ++++++---- scripts/generate-project.sh | 12 ++++++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 867d74a..b582d5a 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,5 @@ test_output derived_data Gemfile.lock .bundle -reports-*/ \ No newline at end of file +reports-*/ +.env \ No newline at end of file diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index 3d4769a..4176c82 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -81,6 +81,6 @@ let project = Project( arguments: .arguments(environmentVariables: ["IS_TESTING": "true"])), runAction: .runAction(configuration: .debug, executable: .project(path: ".", target: moduleName), - arguments: .arguments(environmentVariables: developmentEnv))) + arguments: .arguments(environmentVariables: envs))) ] ) diff --git a/Tuist/ProjectDescriptionHelpers/Project+Template.swift b/Tuist/ProjectDescriptionHelpers/Project+Template.swift index 996e655..5cf2d28 100644 --- a/Tuist/ProjectDescriptionHelpers/Project+Template.swift +++ b/Tuist/ProjectDescriptionHelpers/Project+Template.swift @@ -4,10 +4,12 @@ public enum ModuleTargets: Equatable { case test, testing, interfaces, app, source } -let cmApiBaseURL = EnvironmentVariable(stringLiteral: "https://pro-api.coinmarketcap.com") +let cmApiBaseURL = Environment.cmApiBaseUrl.getString(default: "") +let cmApiKey = Environment.cmApiKey.getString(default: "") -public let developmentEnv: [String: EnvironmentVariable] = [ - "CM_API_BASE_URL": cmApiBaseURL, +public let envs: [String: EnvironmentVariable] = [ + "CM_API_BASE_URL": EnvironmentVariable(stringLiteral: cmApiBaseURL), + "CM_API_KEY": EnvironmentVariable(stringLiteral: cmApiKey) ] public let iOSDeploymentTarget: DeploymentTargets = .iOS("15.0") @@ -116,7 +118,7 @@ public extension Project { testAction: targets.contains(.test) ? .targets(["\(moduleName)Tests"]) : nil, runAction: .runAction( configuration: .debug, - arguments: shouldSetEnvVars ? .arguments(environmentVariables: developmentEnv) : nil + arguments: shouldSetEnvVars ? .arguments(environmentVariables: envs) : nil ) ) ] diff --git a/scripts/generate-project.sh b/scripts/generate-project.sh index 4d62bd8..b47380e 100644 --- a/scripts/generate-project.sh +++ b/scripts/generate-project.sh @@ -1,2 +1,14 @@ +#!/bin/bash + +# Verifica se o ficheiro .env existe +if [ -f .env ]; then + # Lê o ficheiro linha a linha e exporta as variáveis + export $(grep -v '^#' .env | xargs) + echo "✅ Variáveis de ambiente carregadas do .env" +else + echo "⚠️ Ficheiro .env não encontrado!" +fi + +# Executa os comandos do Tuist tuist install tuist generate \ No newline at end of file From 220780c055e9400e262b1edf7cb900fa64a3a041 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Mon, 9 Feb 2026 23:03:03 -0300 Subject: [PATCH 14/16] feat: info cell (#29) --- .../Sources/Components/InfoCell.swift | 222 ++++++++++++++++++ .../Sources/Components/Skeleton.swift | 37 +++ .../Sources/Service/DetailService.swift | 4 +- .../Sources/View/AssetTableViewCell.swift | 6 +- .../Tests/Service/DetailServiceTests.swift | 14 +- Projects/Home/Interfaces/Model/Status.swift | 14 +- .../Home/Sources/Model/HomeViewState.swift | 2 +- .../Protocols/HomeViewModelProtocol.swift | 3 + .../Home/Sources/Service/HomeService.swift | 4 +- .../Sources/View/HomeViewController.swift | 126 +++++----- .../Sources/ViewModel/HomeViewModel.swift | 47 +++- .../Home/Tests/Doubles/HomeViewModelSpy.swift | 14 ++ .../Home/Tests/Service/HomeServiceTests.swift | 24 +- .../Tests/View/HomeViewControllerTests.swift | 44 +++- .../Tests/ViewModel/HomeViewModelTests.swift | 45 +++- 15 files changed, 510 insertions(+), 96 deletions(-) create mode 100644 Projects/DesignSystem/Sources/Components/InfoCell.swift create mode 100644 Projects/DesignSystem/Sources/Components/Skeleton.swift diff --git a/Projects/DesignSystem/Sources/Components/InfoCell.swift b/Projects/DesignSystem/Sources/Components/InfoCell.swift new file mode 100644 index 0000000..4820ee4 --- /dev/null +++ b/Projects/DesignSystem/Sources/Components/InfoCell.swift @@ -0,0 +1,222 @@ +import UIKit + +public final class InfoCell: UITableViewCell { + + public static let identifier = "InfoCell" + + // MARK: - Models + public enum State { + case loaded(InfoCellModel) + case partialLoaded(String) + case loading + } + + public struct InfoCellModel { + public let url: String + public let title: String + public let subtitle: String + public let detail: String + + public init(url: String, title: String, subtitle: String, detail: String) { + self.url = url + self.title = title + self.subtitle = subtitle + self.detail = detail + } + } + + // MARK: - UI Components + private lazy var containerView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .secondarySystemGroupedBackground + view.layer.cornerRadius = 12 + view.clipsToBounds = true + return view + }() + + private lazy var iconImageView = makeImageView() + private lazy var titleLabel = makeLabel(font: .systemFont(ofSize: 17), color: .label) + private lazy var subtitleLabel = makeLabel(font: .systemFont(ofSize: 15), color: .systemGreen) + private lazy var detailLabel = makeLabel(font: .systemFont(ofSize: 15), color: .secondaryLabel) + + private lazy var chevronImageView: UIImageView = { + let config = UIImage.SymbolConfiguration(pointSize: 14, weight: .semibold) + let imageView = UIImageView(image: UIImage(systemName: "chevron.right", withConfiguration: config)) + imageView.tintColor = .tertiaryLabel + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private lazy var textStackView: UIStackView = { + let stack = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel, detailLabel]) + stack.axis = .vertical + stack.spacing = 4 + stack.translatesAutoresizingMaskIntoConstraints = false + return stack + }() + + // MARK: - Init + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setupView() + } + + required init?(coder: NSCoder) { nil } + + public override func prepareForReuse() { + super.prepareForReuse() + [iconImageView, titleLabel, subtitleLabel, detailLabel].forEach { $0.setSkeleton(false) } + iconImageView.image = nil + titleLabel.text = nil + subtitleLabel.text = nil + detailLabel.text = nil + } + + // MARK: - Public Configuration + public func configure(state: State) { + [iconImageView, titleLabel, subtitleLabel, detailLabel].forEach { $0.setSkeleton(false) } + + switch state { + case let .loaded(model): + titleLabel.text = model.title + subtitleLabel.text = model.subtitle + detailLabel.text = model.detail + iconImageView.image = UIImage(systemName: "bahtsign.bank.building.fill") + loadImage(from: model.url) + + case let .partialLoaded(title): + iconImageView.image = UIImage(systemName: "bahtsign.bank.building.fill") + titleLabel.text = title + subtitleLabel.text = " "; subtitleLabel.setSkeleton(true) + detailLabel.text = " "; detailLabel.setSkeleton(true) + + case .loading: + iconImageView.setSkeleton(true, cornerRadius: 11) + titleLabel.text = " " + titleLabel.setSkeleton(true) + subtitleLabel.text = " " + subtitleLabel.setSkeleton(true) + detailLabel.text = " " + detailLabel.setSkeleton(true) + } + } +} + +// MARK: - Factory & ViewCode +private extension InfoCell { + func makeLabel(font: UIFont, color: UIColor) -> UILabel { + let label = UILabel() + label.font = font + label.textColor = color + label.translatesAutoresizingMaskIntoConstraints = false + return label + } + + func makeImageView() -> UIImageView { + let imageView = UIImageView() + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + imageView.layer.cornerRadius = 12 + imageView.backgroundColor = .secondarySystemFill + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + } + + private func loadImage(from urlString: String) { + guard let url = URL(string: urlString) else { return } + Task { + do { + let (data, _) = try await URLSession.shared.data(from: url) + if let image = UIImage(data: data) { + await MainActor.run { iconImageView.image = image } + } + } catch {} + } + } +} + +extension InfoCell: ViewCode { + public func buildViewHierarch() { + contentView.addSubview(containerView) + [iconImageView, + textStackView, + chevronImageView].forEach { containerView.addSubview($0) } + } + + public func setUpConstraints() { + let horizontalPadding = DSSpacings.large.rawValue + let verticalPadding = DSSpacings.small.rawValue + + NSLayoutConstraint.activate([ + containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 84), + + containerView.topAnchor.constraint(greaterThanOrEqualTo: contentView.topAnchor, + constant: verticalPadding), + containerView.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, + constant: -verticalPadding), + containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, + constant: horizontalPadding), + containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, + constant: -horizontalPadding), + containerView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + + iconImageView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), + iconImageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, + constant: horizontalPadding), + iconImageView.widthAnchor.constraint(equalToConstant: 44), + iconImageView.heightAnchor.constraint(equalToConstant: 44), + + textStackView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), + textStackView.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, + constant: 12), + textStackView.trailingAnchor.constraint(equalTo: chevronImageView.leadingAnchor, + constant: -12), + textStackView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor, + constant: 12), + textStackView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor, + constant: -12), + + chevronImageView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), + chevronImageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, + constant: -horizontalPadding), + chevronImageView.widthAnchor.constraint(equalToConstant: 14) + ]) + } + + public func additionalConfiguration() { + selectionStyle = .none + backgroundColor = .clear + contentView.backgroundColor = .clear + } +} + +#if DEBUG +import SwiftUI + +@available(iOS 17.0, *) +#Preview("Loaded") { + let view = InfoCell() + view.configure(state: .loaded(.init( + url: "", + title: "Binance", + subtitle: "Vol: $1234.23", + detail: "Date launched: 12/03/2025" + ))) + return view +} + +@available(iOS 17.0, *) +#Preview("Partial Loaded") { + let view = InfoCell() + view.configure(state: .partialLoaded("Binance")) + return view +} + +@available(iOS 17.0, *) +#Preview("Loading") { + let view = InfoCell() + view.configure(state: .loading) + return view +} +#endif diff --git a/Projects/DesignSystem/Sources/Components/Skeleton.swift b/Projects/DesignSystem/Sources/Components/Skeleton.swift new file mode 100644 index 0000000..88030b6 --- /dev/null +++ b/Projects/DesignSystem/Sources/Components/Skeleton.swift @@ -0,0 +1,37 @@ +// +// +// Created by Vitor Conceicao. +// +// github.com/vitor-rc1 +// +// + +import UIKit + +public extension UIView { + func setSkeleton(_ show: Bool, cornerRadius: CGFloat = 5, width: CGFloat? = nil) { + subviews.first(where: { $0.tag == 999 })?.removeFromSuperview() + + if show { + let skeleton = UIView() + skeleton.backgroundColor = .secondarySystemFill + skeleton.layer.cornerRadius = cornerRadius + skeleton.tag = 999 + skeleton.translatesAutoresizingMaskIntoConstraints = false + + addSubview(skeleton) + + NSLayoutConstraint.activate([ + skeleton.topAnchor.constraint(equalTo: topAnchor), + skeleton.leadingAnchor.constraint(equalTo: leadingAnchor), + skeleton.bottomAnchor.constraint(equalTo: bottomAnchor) + ]) + + NSLayoutConstraint.activate([ + width != nil + ? skeleton.widthAnchor.constraint(equalToConstant: width!) + : skeleton.trailingAnchor.constraint(equalTo: trailingAnchor) + ]) + } + } +} diff --git a/Projects/Detail/Sources/Service/DetailService.swift b/Projects/Detail/Sources/Service/DetailService.swift index 76de45e..f4d5289 100644 --- a/Projects/Detail/Sources/Service/DetailService.swift +++ b/Projects/Detail/Sources/Service/DetailService.swift @@ -29,8 +29,8 @@ final class DetailService: Sendable { case 200...299: return try decodeResponse(data) default: - let error: Status = try decodeResponse(data) - throw DetailServiceError.network(error) + let error: StatusResponse = try decodeResponse(data) + throw DetailServiceError.network(error.status) } } diff --git a/Projects/Detail/Sources/View/AssetTableViewCell.swift b/Projects/Detail/Sources/View/AssetTableViewCell.swift index cf1103b..8da7f34 100644 --- a/Projects/Detail/Sources/View/AssetTableViewCell.swift +++ b/Projects/Detail/Sources/View/AssetTableViewCell.swift @@ -72,11 +72,13 @@ final class AssetTableViewCell: UITableViewCell { private func formatPrice(_ value: Double) -> String { let formatter = NumberFormatter() formatter.numberStyle = .currency - formatter.currencySymbol = "$ " - formatter.maximumFractionDigits = 2 + formatter.currencySymbol = "$" formatter.minimumFractionDigits = 2 + formatter.maximumFractionDigits = 2 + formatter.usesGroupingSeparator = true formatter.groupingSeparator = "." formatter.decimalSeparator = "," + return formatter.string(from: NSNumber(value: value)) ?? "$ 0,00" } } diff --git a/Projects/Detail/Tests/Service/DetailServiceTests.swift b/Projects/Detail/Tests/Service/DetailServiceTests.swift index 1a16e8b..bd1fbfd 100644 --- a/Projects/Detail/Tests/Service/DetailServiceTests.swift +++ b/Projects/Detail/Tests/Service/DetailServiceTests.swift @@ -72,12 +72,14 @@ struct DetailServiceTests { func testFetchExchangeAssetsNetworkError() async throws { let (sut, networkSpy) = makeSut() let mockResponse = """ - { - "timestamp": "2024-01-01T00:00:00.000Z", - "error_code": 404, - "error_message": "Exchange not found", - "elapsed": 10, - "credit_count": 1 + { + "status": { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": 404, + "error_message": "Exchange not found", + "elapsed": 10, + "credit_count": 1 + } } """ let data = try #require(mockResponse.data(using: .utf8)) diff --git a/Projects/Home/Interfaces/Model/Status.swift b/Projects/Home/Interfaces/Model/Status.swift index eaf5596..b5fe4be 100644 --- a/Projects/Home/Interfaces/Model/Status.swift +++ b/Projects/Home/Interfaces/Model/Status.swift @@ -8,12 +8,16 @@ import Foundation +public struct StatusResponse: Equatable, Sendable, Codable { + public let status: Status +} + public struct Status: Equatable, Sendable { - let timestamp: String - let errorCode: Int? - let errorMessage: String? - let elapsed: Int - let creditCount: Int + public let timestamp: String + public let errorCode: Int? + public let errorMessage: String? + public let elapsed: Int + public let creditCount: Int public init(timestamp: String, errorCode: Int? = nil, diff --git a/Projects/Home/Sources/Model/HomeViewState.swift b/Projects/Home/Sources/Model/HomeViewState.swift index b55f15f..3b20c20 100644 --- a/Projects/Home/Sources/Model/HomeViewState.swift +++ b/Projects/Home/Sources/Model/HomeViewState.swift @@ -13,5 +13,5 @@ enum HomeViewState: Equatable { case loadingMore case empty case loaded - case error(String) + case error(String, String?) } diff --git a/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift b/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift index d8cb8c3..7f67cca 100644 --- a/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift +++ b/Projects/Home/Sources/Protocols/HomeViewModelProtocol.swift @@ -12,9 +12,12 @@ import Foundation @MainActor protocol HomeViewModelProtocol: AnyObject { var delegate: HomeViewModelDelegate? { get set } + var state: HomeViewState { get } var numberOfItems: Int { get } func loadData() func item(at index: Int) -> Exchange func didSelectRow(at index: Int) + func formatPrice(_ value: Double) -> String + func formatDate(_ date: String) -> String } diff --git a/Projects/Home/Sources/Service/HomeService.swift b/Projects/Home/Sources/Service/HomeService.swift index 69b70a6..041d67b 100644 --- a/Projects/Home/Sources/Service/HomeService.swift +++ b/Projects/Home/Sources/Service/HomeService.swift @@ -29,8 +29,8 @@ final class HomeService: Sendable { case 200...299: return try decodeResponse(data) default: - let error: Status = try decodeResponse(data) - throw ServiceError.network(error) + let error: StatusResponse = try decodeResponse(data) + throw ServiceError.network(error.status) } } diff --git a/Projects/Home/Sources/View/HomeViewController.swift b/Projects/Home/Sources/View/HomeViewController.swift index f7b97d3..c0bf436 100644 --- a/Projects/Home/Sources/View/HomeViewController.swift +++ b/Projects/Home/Sources/View/HomeViewController.swift @@ -6,6 +6,7 @@ // // +import DesignSystem import UIKit class HomeViewController: UIViewController { @@ -13,22 +14,17 @@ class HomeViewController: UIViewController { private let viewModel: HomeViewModelProtocol private lazy var tableView: UITableView = { - let tableView = UITableView() + let tableView = UITableView(frame: .zero, style: .plain) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + tableView.register(InfoCell.self, forCellReuseIdentifier: InfoCell.identifier) tableView.isHidden = true tableView.delegate = self tableView.dataSource = self + tableView.separatorStyle = .none return tableView }() - private lazy var loadingIndicator: UIActivityIndicatorView = { - let indicator = UIActivityIndicatorView(style: .large) - indicator.translatesAutoresizingMaskIntoConstraints = false - indicator.hidesWhenStopped = true - return indicator - }() - private lazy var footerSpinner: UIActivityIndicatorView = { let spinner = UIActivityIndicatorView(style: .medium) spinner.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44) @@ -36,13 +32,11 @@ class HomeViewController: UIViewController { return spinner }() - private lazy var messageLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textAlignment = .center - label.numberOfLines = 0 - label.isHidden = true - return label + private lazy var errorView: ErrorView = { + let view = ErrorView() + view.translatesAutoresizingMaskIntoConstraints = false + view.isHidden = true + return view }() init(viewModel: HomeViewModelProtocol) { @@ -56,34 +50,40 @@ class HomeViewController: UIViewController { super.viewDidLoad() view.backgroundColor = .systemBackground title = "Exchanges" - setupLayout() + setupView() tableView.tableFooterView = footerSpinner - viewModel.delegate = self viewModel.loadData() } +} - private func setupLayout() { +extension HomeViewController: ViewCode { + func buildViewHierarch() { view.addSubview(tableView) - view.addSubview(loadingIndicator) - view.addSubview(messageLabel) + view.addSubview(errorView) + } + func setUpConstraints() { NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), - loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor), - - messageLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), - messageLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor), - messageLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), - messageLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20) + errorView.topAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.topAnchor), + errorView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + errorView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + errorView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor), + errorView.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) } + + func additionalConfiguration() { + errorView.retryAction = { [weak self] in + self?.viewModel.loadData() + } + } } // MARK: - Delegate (Updates) @@ -91,33 +91,27 @@ extension HomeViewController: HomeViewModelDelegate { func didUpdateState(_ state: HomeViewState) { switch state { case .loading: - loadingIndicator.startAnimating() - tableView.isHidden = true - messageLabel.isHidden = true - + tableView.isHidden = false + errorView.isHidden = true case .loadingMore: footerSpinner.startAnimating() - case .loaded: - loadingIndicator.stopAnimating() footerSpinner.stopAnimating() - messageLabel.isHidden = true + errorView.isHidden = true tableView.isHidden = false tableView.reloadData() - case .empty: - loadingIndicator.stopAnimating() - messageLabel.text = "No exchanges found.." - messageLabel.isHidden = false - - case .error(let msg): - loadingIndicator.stopAnimating() + errorView.configure(title: "No exchanges found..", + message: "Try again later or check your connection.") + errorView.isHidden = false + case let .error(msg, code): + tableView.isHidden = true footerSpinner.stopAnimating() if viewModel.numberOfItems == 0 { - messageLabel.text = msg - messageLabel.isHidden = false - } else { - print(msg) + errorView.configure(title: "Failed to load Exchanges", + message: msg, + code: code) + errorView.isHidden = false } } } @@ -126,25 +120,39 @@ extension HomeViewController: HomeViewModelDelegate { // MARK: - TableView (Pagination & Cells) extension HomeViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return viewModel.numberOfItems + switch viewModel.state { + case .loading: + return 3 + default: + return viewModel.numberOfItems + } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) - let item = viewModel.item(at: indexPath.row) - - var content = cell.defaultContentConfiguration() - content.text = item.name - - if item.isLoadingDetails { - content.secondaryText = "Loading..." - content.secondaryTextProperties.color = .systemBlue - } else { - content.secondaryText = "See more" - content.secondaryTextProperties.color = .secondaryLabel + guard let cell = tableView.dequeueReusableCell(withIdentifier: InfoCell.identifier, + for: indexPath) as? InfoCell else { + return UITableViewCell() + } + + switch viewModel.state { + case .loading: + cell.configure(state: .loading) + case .loaded: + let item = viewModel.item(at: indexPath.row) + if item.isLoadingDetails { + cell.configure(state: .partialLoaded(item.name)) + } else { + let volPrice = "Vol: \(viewModel.formatPrice(item.spotVolumeUsd ?? 0.0))" + let dateLaunched = "Date launched: \(viewModel.formatDate(item.dateLaunched))" + cell.configure(state: .loaded(.init(url: item.logo, + title: item.name, + subtitle: volPrice, + detail: dateLaunched))) + } + default: + return UITableViewCell() } - cell.contentConfiguration = content return cell } diff --git a/Projects/Home/Sources/ViewModel/HomeViewModel.swift b/Projects/Home/Sources/ViewModel/HomeViewModel.swift index 5385a63..79b5190 100644 --- a/Projects/Home/Sources/ViewModel/HomeViewModel.swift +++ b/Projects/Home/Sources/ViewModel/HomeViewModel.swift @@ -86,9 +86,21 @@ final class HomeViewModel: HomeViewModelProtocol { } catch { isFetching = false if exchanges.isEmpty { - state = .error(error.localizedDescription) + let serviceError = error as? ServiceError + let defaultMessage = "Failed to Load data. Press try again later or check your connection." + let message: String + var code: String? + switch serviceError { + case .decodeFail, .none: + message = defaultMessage + case .network(let status): + message = status.errorMessage ?? defaultMessage + if let statusCode = status.errorCode { + code = String(statusCode) + } + } + state = .error(message, code) } else { - print("Fail to load page: \(error)") state = .loaded } } @@ -116,4 +128,35 @@ final class HomeViewModel: HomeViewModelProtocol { websiteUrl: detail.urls.website.first, twitterUrl: detail.urls.twitter.first) } + + func formatPrice(_ value: Double) -> String { + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.currencySymbol = "$" + formatter.minimumFractionDigits = 2 + formatter.maximumFractionDigits = 2 + formatter.usesGroupingSeparator = true + formatter.groupingSeparator = "." + formatter.decimalSeparator = "," + + formatter.locale = Locale(identifier: "pt_BR") + + return formatter.string(from: NSNumber(value: value)) ?? "$ 0,00" + } + + func formatDate(_ date: String) -> String { + let isoFormatter = ISO8601DateFormatter() + isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + + guard let date = isoFormatter.date(from: date) else { + return date + } + + let displayFormatter = DateFormatter() + displayFormatter.dateStyle = .short + displayFormatter.timeStyle = .none + displayFormatter.locale = Locale.current + + return displayFormatter.string(from: date) + } } diff --git a/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift b/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift index 7f94512..242b9e7 100644 --- a/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift +++ b/Projects/Home/Tests/Doubles/HomeViewModelSpy.swift @@ -13,10 +13,14 @@ import HomeInterfaces @MainActor final class HomeViewModelSpy: HomeViewModelProtocol { + var state: HomeViewState = .loading + enum Method: Equatable { case loadData case item case didSelectRow + case formatPrice + case formatDate } var calledMethods: [Method] = [] @@ -36,4 +40,14 @@ final class HomeViewModelSpy: HomeViewModelProtocol { func didSelectRow(at index: Int) { calledMethods.append(.didSelectRow) } + + func formatPrice(_ value: Double) -> String { + calledMethods.append(.formatPrice) + return "" + } + + func formatDate(_ date: String) -> String { + calledMethods.append(.formatDate) + return "" + } } diff --git a/Projects/Home/Tests/Service/HomeServiceTests.swift b/Projects/Home/Tests/Service/HomeServiceTests.swift index 728d73c..81e6cd8 100644 --- a/Projects/Home/Tests/Service/HomeServiceTests.swift +++ b/Projects/Home/Tests/Service/HomeServiceTests.swift @@ -64,11 +64,13 @@ struct HomeServiceTests { )) let mockResponse = """ { - "timestamp": "2024-01-01T00:00:00.000Z", - "error_code": 401, - "error_message": "Invalid API Key", - "elapsed": 10, - "credit_count": 1 + "status": { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": 401, + "error_message": "Invalid API Key", + "elapsed": 10, + "credit_count": 1 + } } """ let data = mockResponse.data(using: .utf8)! @@ -149,11 +151,13 @@ struct HomeServiceTests { let mockResponse = """ { - "timestamp": "2024-01-01T00:00:00.000Z", - "error_code": 500, - "error_message": "Internal Server Error", - "elapsed": 10, - "credit_count": 1 + "status": { + "timestamp": "2024-01-01T00:00:00.000Z", + "error_code": 500, + "error_message": "Internal Server Error", + "elapsed": 10, + "credit_count": 1 + } } """ let data = mockResponse.data(using: .utf8)! diff --git a/Projects/Home/Tests/View/HomeViewControllerTests.swift b/Projects/Home/Tests/View/HomeViewControllerTests.swift index 6489f1b..b7044cf 100644 --- a/Projects/Home/Tests/View/HomeViewControllerTests.swift +++ b/Projects/Home/Tests/View/HomeViewControllerTests.swift @@ -9,6 +9,7 @@ import HomeInterfaces import Testing import UIKit +import DesignSystem @testable import Home @@ -27,9 +28,22 @@ struct HomeViewControllerTests { #expect(viewModelSpy.delegate != nil) } - @Test("GIVEN viewController WHEN tableView numberOfRows is called THEN returns viewModel numberOfItems") - func testTableViewNumberOfRows() throws { + @Test("GIVEN viewController in loading state WHEN tableView numberOfRows is called THEN returns 3") + func testTableViewNumberOfRowsLoading() throws { let (sut, viewModelSpy) = makeSut() + viewModelSpy.state = .loading + sut.loadView() + sut.viewDidLoad() + + let numberOfRows = sut.tableView(UITableView(), numberOfRowsInSection: 0) + + #expect(numberOfRows == 3) + } + + @Test("GIVEN viewController in loaded state WHEN tableView numberOfRows is called THEN returns viewModel numberOfItems") + func testTableViewNumberOfRowsLoaded() throws { + let (sut, viewModelSpy) = makeSut() + viewModelSpy.state = .loaded viewModelSpy.numberOfItems = 5 sut.loadView() sut.viewDidLoad() @@ -39,8 +53,23 @@ struct HomeViewControllerTests { #expect(numberOfRows == 5) } - @Test("GIVEN viewController WHEN tableView cellForRow is called THEN returns configured cell") - func testTableViewCellForRow() throws { + @Test("GIVEN viewController in loading state WHEN tableView cellForRow is called THEN returns InfoCell in loading state") + func testTableViewCellForRowLoading() throws { + let (sut, viewModelSpy) = makeSut() + viewModelSpy.state = .loading + sut.loadView() + sut.viewDidLoad() + + let tableView = UITableView() + tableView.register(InfoCell.self, forCellReuseIdentifier: InfoCell.identifier) + + let cell = sut.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 0)) + + #expect(cell is InfoCell) + } + + @Test("GIVEN viewController in loaded state WHEN tableView cellForRow is called THEN returns configured InfoCell") + func testTableViewCellForRowLoaded() throws { let (sut, viewModelSpy) = makeSut() let exchange = Exchange( id: 1, @@ -50,6 +79,7 @@ struct HomeViewControllerTests { takerFee: 0.002, dateLaunched: "2017-07-14" ) + viewModelSpy.state = .loaded viewModelSpy.itemsToReturn = [exchange] viewModelSpy.numberOfItems = 1 @@ -57,12 +87,14 @@ struct HomeViewControllerTests { sut.viewDidLoad() let tableView = UITableView() - tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + tableView.register(InfoCell.self, forCellReuseIdentifier: InfoCell.identifier) let cell = sut.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 0)) + #expect(cell is InfoCell) #expect(viewModelSpy.calledMethods.contains(.item)) - #expect(cell.textLabel?.text == nil || cell.contentConfiguration != nil) + #expect(viewModelSpy.calledMethods.contains(.formatPrice)) + #expect(viewModelSpy.calledMethods.contains(.formatDate)) } @Test("GIVEN viewController WHEN tableView didSelectRow is called THEN calls viewModel didSelectRow") diff --git a/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift b/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift index 9b182c0..680a6a9 100644 --- a/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift +++ b/Projects/Home/Tests/ViewModel/HomeViewModelTests.swift @@ -34,6 +34,7 @@ struct HomeViewModelTests { @Test("GIVEN empty state WHEN loadData fails THEN updates state to error") func testLoadDataError() async throws { let (sut, doubles) = makeSut() + let messageError = "Failed to Load data. Press try again later or check your connection." let error = NSError(domain: "test", code: 1, userInfo: [NSLocalizedDescriptionKey: "Network error"]) doubles.serviceSpy.fetchExchangesListResult = .failure(error) @@ -44,7 +45,7 @@ struct HomeViewModelTests { #expect(doubles.serviceSpy.calledMethods.contains(.fetchExchangesList)) #expect(sut.numberOfItems == 0) #expect(doubles.delegateSpy.calledMethods == [.didUpdateState(.loading), - .didUpdateState(.error("Network error"))]) + .didUpdateState(.error(messageError, nil))]) } @Test("GIVEN empty state WHEN loadData returns empty array THEN updates state to empty") @@ -101,6 +102,48 @@ struct HomeViewModelTests { #expect(doubles.coordinatorDelegateSpy.calledMethods == [.navigateToDetails(exchange)]) } + @Test("GIVEN a value WHEN formatPrice is called THEN returns formatted currency string", + arguments: [ + (1000000.50, "1.000.000,50"), + (0.0, "0,00"), + (1234.5, "1.234,50") + ]) + func testFormatPrice(value: Double, expectedString: String) { + let (sut, _) = makeSut() + + let result = sut.formatPrice(value) + + #expect(result.contains(expectedString)) + } + + @Test("GIVEN a valid ISO8601 date WHEN formatDate is called THEN returns localized short date") + func testFormatDateValid() { + let (sut, _) = makeSut() + + let result = sut.formatDate("2017-07-14T00:00:00.000Z") + + let expectedFormatter = DateFormatter() + expectedFormatter.dateStyle = .short + expectedFormatter.timeStyle = .none + expectedFormatter.locale = Locale.current + + let isoFormatter = ISO8601DateFormatter() + isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + let date = isoFormatter.date(from: "2017-07-14T00:00:00.000Z")! + let expected = expectedFormatter.string(from: date) + + #expect(result == expected) + } + + @Test("GIVEN an invalid date string WHEN formatDate is called THEN returns the original string") + func testFormatDateInvalid() { + let (sut, _) = makeSut() + + let result = sut.formatDate("not-a-date") + + #expect(result == "not-a-date") + } + @Test("GIVEN loaded exchanges WHEN item is requested at valid index THEN returns correct exchange") func testItemAtIndex() async throws { let (sut, doubles) = makeSut() From 9701805a9b666ad1837d701d41aa938a9a5f3dbb Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Tue, 10 Feb 2026 09:05:06 -0300 Subject: [PATCH 15/16] fix: adjust old ios not compatible bird image (#30) --- Projects/Detail/Sources/View/DetailHeaderView.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Projects/Detail/Sources/View/DetailHeaderView.swift b/Projects/Detail/Sources/View/DetailHeaderView.swift index 98ebb49..d8412e0 100644 --- a/Projects/Detail/Sources/View/DetailHeaderView.swift +++ b/Projects/Detail/Sources/View/DetailHeaderView.swift @@ -100,7 +100,11 @@ final class DetailHeaderView: UIView { let button = UIButton(type: .system) button.translatesAutoresizingMaskIntoConstraints = false let config = UIImage.SymbolConfiguration(pointSize: 18) - button.setImage(UIImage(systemName: "bird.fill", withConfiguration: config), for: .normal) + if #available(iOS 16.0, *) { + button.setImage(UIImage(systemName: "bird.fill", withConfiguration: config), for: .normal) + } else { + button.setImage(UIImage(systemName: "bubble.left", withConfiguration: config), for: .normal) + } button.tintColor = .white button.backgroundColor = .systemBlue button.layer.cornerRadius = 18 From 8a324430a163b61c345acaf40c3651ef663880b1 Mon Sep 17 00:00:00 2001 From: Vitor Rodrigues <42953452+vitor-rc1@users.noreply.github.com> Date: Tue, 10 Feb 2026 09:26:52 -0300 Subject: [PATCH 16/16] doc: readme update (#31) --- .github/workflows/pr_status.yml | 7 +- README.md | 168 +++++++++++++++++- readme-assets/dark/error.png | Bin 0 -> 115130 bytes readme-assets/dark/exchange-detail.png | Bin 0 -> 311002 bytes readme-assets/dark/exchange-list-loaded.png | Bin 0 -> 390832 bytes readme-assets/dark/exchange-list-loading.png | Bin 0 -> 98928 bytes .../dark/exchange-list-pre-loaded.png | Bin 0 -> 191676 bytes readme-assets/graph-dependency.png | Bin 0 -> 150804 bytes readme-assets/light/error.png | Bin 0 -> 124567 bytes readme-assets/light/exchange-detail.png | Bin 0 -> 300762 bytes readme-assets/light/exchange-list-loaded.png | Bin 0 -> 382001 bytes readme-assets/light/exchange-list-loading.png | Bin 0 -> 97688 bytes .../light/exchange-list-pre-loaded.png | Bin 0 -> 180127 bytes 13 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 readme-assets/dark/error.png create mode 100644 readme-assets/dark/exchange-detail.png create mode 100644 readme-assets/dark/exchange-list-loaded.png create mode 100644 readme-assets/dark/exchange-list-loading.png create mode 100644 readme-assets/dark/exchange-list-pre-loaded.png create mode 100644 readme-assets/graph-dependency.png create mode 100644 readme-assets/light/error.png create mode 100644 readme-assets/light/exchange-detail.png create mode 100644 readme-assets/light/exchange-list-loaded.png create mode 100644 readme-assets/light/exchange-list-loading.png create mode 100644 readme-assets/light/exchange-list-pre-loaded.png diff --git a/.github/workflows/pr_status.yml b/.github/workflows/pr_status.yml index 4827269..b691df6 100644 --- a/.github/workflows/pr_status.yml +++ b/.github/workflows/pr_status.yml @@ -93,8 +93,11 @@ jobs: danger: name: Danger Code Review runs-on: ubuntu-latest - needs: [test] - if: always() + needs: [test, paths-filter] + if: | + needs.paths-filter.result == 'success' && + fromJson(needs.paths-filter.outputs.matrix).target[0] != null && + needs.test.result == 'success' permissions: pull-requests: write contents: read diff --git a/README.md b/README.md index 655453b..d4cf033 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,167 @@ -# exchanges-app +# Exchanges App A simple iOS application that displays a list of cryptocurrency exchanges and their details using the CoinMarketCap API. +This app have support to iOS 15+ and is built using Swift 6, UIKit, and follows the MVVM-C and TMA architecture. +[Figma Design](https://www.figma.com/design/OWVBNp9S0F6mbiXfdwOW9G/Exchanges-app?node-id=0-1&t=AvN5N9ABLPwF8tJy-1) + +--- + +## 📌 Summary +- [Exchanges App](#exchanges-app) + - [📌 Summary](#-summary) +- [Project Setup Guide](#project-setup-guide) + - [Requirements to setup the project](#requirements-to-setup-the-project) + - [Installation Steps](#installation-steps) + - [Dependencies of the project](#dependencies-of-the-project) + - [About the project structure](#about-the-project-structure) + - [Preview](#preview) + - [Exchange List](#exchange-list) + - [Exchange Detail](#exchange-detail) + - [Error](#error) +- [System Design](#system-design) + - [Functional requirements](#functional-requirements) + - [Non-functional requirements](#non-functional-requirements) + - [Data Entities Definitions](#data-entities-definitions) + - [Entity Relationship Diagram](#entity-relationship-diagram) + - [API Endpoints](#api-endpoints) + - [1. List Exchanges (Mapping)](#1-list-exchanges-mapping) + - [2. Exchange Metadata](#2-exchange-metadata) + - [3. Exchange Assets (Holdings)](#3-exchange-assets-holdings) + - [Error Handling \& Status Codes](#error-handling--status-codes) + - [High-Level Design (MVVM-C)](#high-level-design-mvvm-c) + - [Architectural Components](#architectural-components) + +--- + +# Project Setup Guide +## Requirements to setup the project +To set up the project, you will need the following tools installed on your machine: +- [Xcode 26.2+](https://xcodereleases.com/) +- [Homebrew](https://brew.sh/) (for installing dependencies) +- [RubyGems 3.6+](https://rubygems.org/) (for installing dependencies via Bundler) + +## Installation Steps +1. Create API Key: + - Sign up for a free account on [CoinMarketCap API](https://coinmarketcap.com/api/) + - Generate an API key from the dashboard. +2. create .env file in the root of the project and add your CoinMarketCap API key: +``` + TUIST_CM_API_BASE_URL=https://pro-api.coinmarketcap.com + TUIST_CM_API_KEY=ADD_COINMARKETCAP_API_KEY_HERE +``` +3. Install dependencies: + - Open Terminal and navigate to the project directory. + - Run `make local-setup` to install the required project dependencies. + - Run `make generate-project` to generate the project workspace. + +## Dependencies of the project +The project uses the following dependencies: +- [Tuist](https://tuist.io/) for project generation and management. +- [Fastlane](https://fastlane.tools/) for automating build and release processes. +- [SwiftLint](https://github.com/realm/SwiftLint) for code linting and formatting. +- [xcbeautify](https://github.com/tuist/xcbeautify) for beautifying Fastlane build output. +- [Slather](https://github.com/SlatherOrg/slather) for code coverage reports. +- [Danger](https://danger.systems/) for automated code review and quality checks. +- [networkin-package](https://github.com/vitor-rc1/networking-package) SPM parckge for abstracting network layer and API calls. This package was created by me and is used in this project to handle all network requests and responses, providing a clean and modular way to interact with the CoinMarketCap API. +- [Swinject](https://github.com/Swinject/Swinject) for dependency injection, allowing for better separation of concerns and easier testing. +- [Snapshot Testing](https://github.com/pointfreeco/swift-snapshot-testing) for testing the UI components and ensuring they render correctly across different states and configurations. + +## About the project structure +The project is organized into the following main directories: +- `Projects/`: Contains the Application and Features following the TMA architecture. + - `Sources/`: Contains code and utilities used only in the module, except for modules that are shared across multiple features. + - `Tests/`: Contains unit tests for the module. + - `Interfaces/`: Contains protocols and interfaces that define the contract for communication between modules. + - `Resources/`: Contains assets, storyboards, and other resources used by the module. + - `Testing/`: Contains test utilities and mocks used for unit testing to use between modules. +- `Tuist/`: Contains the Tuist configuration files for project generation. +- `fastlane/`: Contains Fastlane configuration files for automating build and release processes. +- `scripts/`: Contains custom scripts for setup, build, and other tasks. + +Using the TMA architecture, the project is organized into modules that represent different features of the app. Each module is self-contained and can be developed and tested independently, promoting separation of concerns and modularity. It's common to only have public code and concrete, but this bring a problem with tests, because we have to create duplicates spies and mocks for each module, so we have a shared Testing folder to avoid this problem. Below is a diagram illustrating the project structure and dependencies between modules: + +TMA Architecture Diagram + +The use of Tuist allows for easy project generation and management, while Fastlane automates the build and release processes, ensuring a smooth development workflow. SwiftLint helps maintain code quality and consistency across the codebase. + +The modules consist of: +- **App:** The main application module that contains the app delegate, scene delegate, and the main coordinator responsible for navigation. +- **Home:** The feature module responsible for displaying the list of cryptocurrency exchanges. +- **Detail:** The feature module responsible for displaying the details of a specific exchange. +- **DependencyInjection:** A shared module that contains the dependency injection container and related configurations. This module is used to manage dependencies across the app and features, ensuring a clean separation of concerns and easier testing. +- **DesisgnSystem:** A shared module that contains reusable UI components, styles, and assets. This module promotes consistency across the app and allows for easy maintenance of the design system. +- **Navigation:** A shared module that contains navigation-related components and utilities, such as coordinators and navigation controllers. This module helps centralize navigation logic and promotes a clean separation of concerns. + +## Preview +

+ 📸 Screenshots +The app consists of two main screens: the Exchange List and the Exchange Detail. Below are screenshots of each screen: + +### Exchange List + + + + + + + + + + + + + + + +
Exchange List ScreenExchange List ScreenExchange List Screen
LoadingPre loadedLoaded
Dark
+ + + + + + + + + + + + + + + +
Exchange List ScreenExchange List ScreenExchange List Screen
LoadingPre loadedLoaded
Light
+ +### Exchange Detail + + + + + + + + + +
Exchange Detail ScreenExchange Detail Screen
Detail DarkDetail Light
+ +### Error + + + + + + + + + +
Exchange List Error ScreenExchange List Error Screen
Error DarkError Light
+
+ +# System Design ## Functional requirements - **User can:** - view a list of cryptocurrency exchanges. - view details of a specific exchange. - - view details of a specific exchange using deeplinks - - visit the exchange's website from the app + - visit the exchange's website and twitter when have url - view the app in light and dark mode - view a loading indicator while data is being fetched - view an error message if data fetching fails @@ -19,6 +174,9 @@ A simple iOS application that displays a list of cryptocurrency exchanges and th - should be performant and load data quickly. - should consider scalability for future features and enhancements. - should follow best practices for iOS development. + - should support iOS 15 and later. + - should be built using Swift 6 and UIKit. + - should follow the MVVM-C architecture for better separation of concerns and testability. ## Data Entities Definitions - **PreLoadedExchanges:** A list of exchanges with basic information (id, name) that is preloaded in the app for quick access. @@ -32,7 +190,7 @@ A simple iOS application that displays a list of cryptocurrency exchanges and th ```mermaid erDiagram - PreLoadedExchange { + ExchangeSummary { Int id String name } @@ -128,7 +286,7 @@ The application architecture is based on the MVVM-C (Model-View-ViewModel + Coor - **Coordinator:** The "brain" of navigation. It removes the responsibility of flow control from View Controllers, making them independent and reusable. It handles the instantiation of ViewControllers and ViewModels. - **ViewModel:** Acts as a mediator between the Model and the View. It holds the business logic, formats data for display, and is completely unaware of the UI framework (UIKit/SwiftUI), which makes it ideal for Unit Testing. - **View (ViewController):** Responsible only for layout and capturing user interactions. It binds to the ViewModel to receive updates. -- **Network / API:** Handles all network requests and responses, abstracting the details of API communication. +- **Service / API:** Handles all network requests and responses, abstracting the details of API communication. Model: Represents the data structures and the business logic layer (Repositories and Services). diff --git a/readme-assets/dark/error.png b/readme-assets/dark/error.png new file mode 100644 index 0000000000000000000000000000000000000000..febfedf03d8988b16dfb24b4f0e11079823a965a GIT binary patch literal 115130 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
U;K8Mf&kM8 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≈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

uNC}Cy5j3j7Bo;XtS^k4SH4={t$SY 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