[PM-26060] Consolidate Store to BitwardenKit (#2065)

This commit is contained in:
Katherine Bertelsen 2025-10-24 08:45:53 -05:00 committed by GitHub
parent fa39bd630b
commit 656617a0f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
174 changed files with 174 additions and 292 deletions

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import SnapshotTesting
import SwiftUI

View File

@ -1,3 +1,4 @@
import BitwardenKit
import Foundation
/// A coordinator that manages navigation for the debug menu.

View File

@ -1,171 +0,0 @@
import BitwardenKit
import Combine
import SwiftUI
/// A `Store` provides an interface for observing and modifying state between a `Processor` and a
/// `View`. A `View` can send actions to the `Processor` through the store and can observe changes
/// that the `Processor` makes to the state.
///
@MainActor
open class Store<State: Sendable, Action: Sendable, Effect: Sendable>: ObservableObject {
// MARK: Properties
/// A cancellable object for the processor's state publisher subscription.
private var cancellable: AnyCancellable?
/// The current state of the store. This is updated from a `Processor` and is able to be
/// observed by a view.
@Published private(set) var state: State
/// A closure that is called when an effect is performed by the view.
private var perform: ((Effect) async -> Void)?
/// A closure that is called when an action is sent from the view.
private var receive: ((Action) -> Void)?
// MARK: Initialization
/// Initialize a `Store` from a `Processor`. This connects the processor to the `Store`. When
/// the processor's state changes, the store's state will update, allowing a view to observe
/// changes to the state and re-render. When an action is sent to the store from a view, the
/// processor will receive the action for processing.
///
/// - Parameter processor: The `Processor` that will receive actions from the store and update
/// the store's state.
///
public init<P: Processor>(processor: P) where P.Action == Action, P.Effect == Effect, P.State == State {
state = processor.state
receive = { processor.receive($0) }
perform = { await processor.perform($0) }
cancellable = processor.statePublisher.sink { [weak self] in self?.state = $0 }
}
/// Initialize a new `Store` from an existing `Store`.
///
/// - Parameters:
/// - parentStore: The existing `Store` used to create the new `Store`.
/// - parentToChildState: A closure that maps state from the parent store to the child store.
/// - map: A closure that maps actions from the `Store` to an action of the parent `Store`.
///
public init<ParentState, ParentAction, ParentEffect>(
parentStore: Store<ParentState, ParentAction, ParentEffect>,
state parentToChildState: @escaping (ParentState) -> State,
mapAction: ((Action) -> ParentAction)?,
mapEffect: ((Effect) -> ParentEffect)?,
) {
state = parentToChildState(parentStore.state)
receive = { action in
guard let mapAction else { return }
parentStore.send(mapAction(action))
}
perform = { effect in
guard let mapEffect else { return }
await parentStore.perform(mapEffect(effect))
}
cancellable = parentStore.$state.sink { [weak self] in self?.state = parentToChildState($0) }
}
// MARK: Methods
/// Send an action to the store. The action will be received by the store's processor or a
/// parent store.
///
/// - Parameter action: The action to send.
///
open func send(_ action: Action) {
receive?(action)
}
/// Performs an asynchronous effect using the store.
///
/// - Parameter effect: The effect to perform.
///
open func perform(_ effect: Effect) async {
await perform?(effect)
}
/// Creates a child `Store` from an existing `Store`. This can be used to create a new `Store`
/// for a view that may be used in conjunction with other stores in the application. Any
/// actions sent from the child store are mapped to a parent's action and sent back to the
/// parent store.
///
/// - Parameters:
/// - state: The store's initial state.
/// - map: A closure that provides a mapping from an action sent by the child store to the
/// parent store's action.
/// - Returns: A child `Store` created from an existing `Store`.
///
open func child<ChildState, ChildAction, ChildEffect>(
state: @escaping (State) -> ChildState,
mapAction: ((ChildAction) -> Action)?,
mapEffect: ((ChildEffect) -> Effect)?,
) -> Store<ChildState, ChildAction, ChildEffect> {
Store<ChildState, ChildAction, ChildEffect>(
parentStore: self,
state: state,
mapAction: mapAction,
mapEffect: mapEffect,
)
}
/// Creates a `Binding` whose value is set from the store's state. When the value is changed,
/// the specified action is sent to the store so that the processor can update its state.
///
/// - Parameters:
/// - get: A closure that provides a value for the binding from the store's state.
/// - stateToAction: A closure that provides a mapping from the binding's value to an action
/// that is sent to the store when the value changes.
/// - Returns: A `Binding` whose value is set from the store's state which triggers an action
/// to be sent back to the store when the value changes.
///
open func binding<LocalState>(
get: @escaping (State) -> LocalState,
send stateToAction: @escaping (LocalState) -> Action,
) -> Binding<LocalState> {
Binding(
get: { get(self.state) },
set: { value, _ in
self.send(stateToAction(value))
},
)
}
/// Creates a `Binding` whose value is set from the store's state asynchronously. When the value is changed,
/// the specified effect is sent to the store so that the processor can update its state.
///
/// - Parameters:
/// - get: A closure that provides a value for the binding from the store's state.
/// - stateToEffect: A closure that provides a mapping from the binding's value to an effect
/// that is sent to the store when the value changes.
/// - Returns: A `Binding` whose value is set from the store's state which triggers an effect
/// to be sent back to the store when the value changes.
///
open func bindingAsync<LocalState>(
get: @escaping (State) -> LocalState,
perform stateToEffect: @escaping (LocalState) -> Effect,
) -> Binding<LocalState> {
Binding(
get: { get(self.state) },
set: { value, _ in
Task {
await self.perform(stateToEffect(value))
}
},
)
}
/// Creates a `Binding` whose value is set from the store's state. This binding is only used for _retrieving_
/// values, and cannot be used to set values in the state. This binding should only be used when a value in a
/// store's state needs to be observed, but not updated.
///
/// - Parameter get: A closure that provides a value for the binding from the store's state.
/// - Returns: A `Binding` whose value is set from the store's state and does not notify the store if the value is
/// updated.
///
open func binding<LocalState>(get: @escaping (State) -> LocalState) -> Binding<LocalState> {
Binding(
get: { get(self.state) },
set: { _ in },
)
}
}

View File

@ -1,106 +0,0 @@
import BitwardenKitMocks
import Foundation
import XCTest
@testable import AuthenticatorShared
@MainActor
class StoreTests: BitwardenTestCase {
var processor: MockProcessor<TestState, TestAction, TestEffect>!
var subject: Store<TestState, TestAction, TestEffect>!
override func setUp() {
super.setUp()
processor = MockProcessor(state: TestState())
subject = Store(processor: processor)
}
/// `send(_:)` forwards the action to the processor for processing.
func testSendAction() {
subject.send(.increment)
XCTAssertEqual(processor.dispatchedActions, [.increment])
processor.dispatchedActions.removeAll()
subject.send(.decrement)
XCTAssertEqual(processor.dispatchedActions, [.decrement])
}
/// `perform(_:)` forwards the effect to the processor for performing.
func testPerformEffect() async {
await subject.perform(.something)
XCTAssertEqual(processor.effects, [.something])
}
/// `child(_:)` creates a child store that maps actions, state, and effects from its parent.
func testChildStore() async {
let childStore = subject.child(state: { $0.child }, mapAction: { .child($0) }, mapEffect: { .child($0) })
XCTAssertEqual(childStore.state.value, "🐣")
childStore.send(.updateValue("🦜"))
XCTAssertEqual(processor.dispatchedActions, [.child(.updateValue("🦜"))])
await childStore.perform(.something)
XCTAssertEqual(processor.effects, [.child(.something)])
processor.state.child.value = "🦜"
XCTAssertEqual(childStore.state.value, "🦜")
}
/// `binding(get:send:)` creates a binding from a value in the state and sends an action to the
/// processor when the binding's value changes.
func testBinding() {
let binding = subject.binding(get: { $0.counter }, send: { .counterChanged($0) })
XCTAssertEqual(binding.wrappedValue, 0)
binding.wrappedValue = 1
XCTAssertEqual(processor.dispatchedActions, [.counterChanged(1)])
processor.dispatchedActions.removeAll()
binding.wrappedValue = 20
XCTAssertEqual(processor.dispatchedActions, [.counterChanged(20)])
}
/// `binding(get:)` creates a binding from a value in the state that does not update the state when the binding's
/// value is changed.
func testBindingGetOnly() {
let binding = subject.binding(get: { $0.counter })
XCTAssertEqual(binding.wrappedValue, 0)
binding.wrappedValue = 1
XCTAssertEqual(processor.dispatchedActions, [])
XCTAssertEqual(processor.state.counter, 0)
}
}
enum ChildAction: Equatable {
case updateValue(String)
}
struct ChildState: Equatable {
var value = "🐣"
}
enum ChildEffect: Equatable {
case something
}
enum TestAction: Equatable {
case child(ChildAction)
case counterChanged(Int)
case decrement
case increment
}
enum TestEffect: Equatable {
case child(ChildEffect)
case something
}
struct TestState: Equatable {
var child = ChildState()
var counter = 0
}

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import SnapshotTesting
import SwiftUI

View File

@ -1,3 +1,4 @@
import BitwardenKit
import SwiftUI
// MARK: - TutorialCoordinator

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import SnapshotTesting
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,3 +1,4 @@
import BitwardenKit
import OSLog
import SwiftUI

View File

@ -1,4 +1,5 @@
import AVFoundation
import BitwardenKit
import SwiftUI
// MARK: - AuthenticatorKeyCaptureDelegate

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,5 +1,6 @@
// swiftlint:disable:this file_name
import AVFoundation
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,5 +1,6 @@
// swiftlint:disable:this file_name
import AVFoundation
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,7 +1,6 @@
import BitwardenKitMocks
import BitwardenShared
import BitwardenKit
extension Store {
public extension Store {
static func mock(state: State) -> Store<State, Action, Effect> {
Store(processor: MockProcessor(state: state))
}

View File

@ -1,4 +1,3 @@
import BitwardenKit
import Combine
import SwiftUI
@ -15,7 +14,7 @@ open class Store<State: Sendable, Action: Sendable, Effect: Sendable>: Observabl
/// The current state of the store. This is updated from a `Processor` and is able to be
/// observed by a view.
@Published private(set) var state: State
@Published public private(set) var state: State
/// A closure that is called when an effect is performed by the view.
private var perform: ((Effect) async -> Void)?

View File

@ -1,9 +1,8 @@
import BitwardenKit
import BitwardenKitMocks
import Foundation
import XCTest
@testable import BitwardenShared
// MARK: - StoreTests
class StoreTests: BitwardenTestCase {

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,3 +1,4 @@
import BitwardenKit
import BitwardenResources
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import SnapshotTesting
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import BitwardenSdk

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import BitwardenSdk

View File

@ -1,3 +1,4 @@
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import BitwardenSdk

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import BitwardenSdk

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import BitwardenSdk

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenSdk
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenSdk
import SwiftUI

View File

@ -1,3 +1,4 @@
import BitwardenKit
import BitwardenKitMocks
import BitwardenSdk
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,3 +1,4 @@
import BitwardenKit
import UIKit
// MARK: - SearchHandler

View File

@ -1,3 +1,4 @@
import BitwardenKit
import SwiftUI
/// A scroll view that contains the guided tour content.

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SwiftUI

View File

@ -1,3 +1,4 @@
import BitwardenKit
import Foundation
/// An object that is notified when the debug menu is dismissed.

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,3 +1,5 @@
import BitwardenKit
// MARK: - ExtensionSetupCoordinator
/// A coordinator that manages navigation in the vault tab.

View File

@ -1,3 +1,5 @@
import BitwardenKit
/// A coordinator that manages navigation for the login request view.
///
final class LoginRequestCoordinator: Coordinator, HasStackNavigator {

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import ViewInspector

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import SnapshotTesting

View File

@ -1,4 +1,5 @@
// swiftlint:disable:this file_name
import BitwardenKit
import BitwardenKitMocks
import BitwardenResources
import XCTest

View File

@ -1,3 +1,4 @@
import BitwardenKit
import SwiftUI
// MARK: - PasswordAutoFillCoordinatorDelegate

Some files were not shown because too many files have changed in this diff Show More