mirror of
https://github.com/otaviocc/Triton.git
synced 2026-01-29 19:54:27 +00:00
Add SwiftLint
This commit is contained in:
parent
d3b596c26f
commit
ee174ab836
66 changed files with 395 additions and 213 deletions
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
|
|
@ -2,9 +2,7 @@ name: Build
|
|||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
|||
11
.github/workflows/swiftformat.yml
vendored
11
.github/workflows/swiftformat.yml
vendored
|
|
@ -2,9 +2,7 @@ name: SwiftFormat Check
|
|||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
swiftformat:
|
||||
|
|
@ -19,9 +17,4 @@ jobs:
|
|||
run: brew install swiftformat
|
||||
|
||||
- name: Check code formatting
|
||||
run: |
|
||||
swiftformat --lint .
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Code formatting issues detected. Please run 'swiftformat .' locally to fix."
|
||||
exit 1
|
||||
fi
|
||||
run: swiftformat --lint .
|
||||
|
|
|
|||
20
.github/workflows/swiftlint.yml
vendored
Normal file
20
.github/workflows/swiftlint.yml
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: SwiftLint Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
swiftlint:
|
||||
name: SwiftLint
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install SwiftLint
|
||||
run: brew install swiftlint
|
||||
|
||||
- name: Run SwiftLint
|
||||
run: swiftlint lint --reporter github-actions-logging
|
||||
4
.github/workflows/unit-tests.yml
vendored
4
.github/workflows/unit-tests.yml
vendored
|
|
@ -2,9 +2,7 @@ name: Unit Tests
|
|||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
|
|
|||
64
.swiftlint.yml
Normal file
64
.swiftlint.yml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Minimal SwiftLint configuration
|
||||
# SwiftFormat handles all formatting, so SwiftLint focuses on code quality and best practices
|
||||
|
||||
disabled_rules:
|
||||
- line_length
|
||||
- opening_brace
|
||||
- function_parameter_count
|
||||
- nesting
|
||||
- large_tuple
|
||||
- type_name
|
||||
- force_unwrapping
|
||||
- blanket_disable_command
|
||||
|
||||
opt_in_rules:
|
||||
- array_init
|
||||
- contains_over_first_not_nil
|
||||
- convenience_type
|
||||
- discouraged_assert
|
||||
- discouraged_object_literal
|
||||
- empty_count
|
||||
- empty_string
|
||||
- empty_xctest_method
|
||||
- explicit_init
|
||||
- fatal_error_message
|
||||
- first_where
|
||||
- force_cast
|
||||
- force_try
|
||||
- implicit_return
|
||||
- joined_default_parameter
|
||||
- last_where
|
||||
- legacy_random
|
||||
- lower_acl_than_parent
|
||||
- multiline_function_chains
|
||||
- multiline_parameters
|
||||
- multiline_parameters_brackets
|
||||
- no_fallthrough_only
|
||||
- operator_usage_whitespace
|
||||
- overridden_super_call
|
||||
- prohibited_super_call
|
||||
- redundant_nil_coalescing
|
||||
- single_test_class
|
||||
- sorted_first_last
|
||||
- static_operator
|
||||
- switch_case_alignment
|
||||
- trailing_closure
|
||||
- unavailable_function
|
||||
- unneeded_parentheses_in_closure_argument
|
||||
- unused_control_flow_label
|
||||
- vertical_whitespace_closing_braces
|
||||
- xct_specific_matcher
|
||||
- xctfail_message
|
||||
- yoda_condition
|
||||
|
||||
multiline_parameters:
|
||||
allows_single_line: false
|
||||
|
||||
excluded:
|
||||
- .build
|
||||
- "**/.build"
|
||||
- DerivedData
|
||||
- Pods
|
||||
- Carthage
|
||||
- .git
|
||||
- node_modules
|
||||
|
|
@ -207,6 +207,7 @@ struct TritonEnvironment: TritonEnvironmentProtocol {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
authSessionServiceFactory: any AuthSessionServiceFactoryProtocol,
|
||||
sessionServiceFactory: any SessionServiceFactoryProtocol,
|
||||
|
|
@ -233,11 +234,9 @@ struct TritonEnvironment: TritonEnvironmentProtocol {
|
|||
allocation: .static
|
||||
) { container in
|
||||
let authSessionService = container.resolve() as any AuthSessionServiceProtocol
|
||||
return networkClient.makeOMGAPIClient(
|
||||
authTokenProvider: {
|
||||
return networkClient.makeOMGAPIClient {
|
||||
await authSessionService.accessToken
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
container.register(
|
||||
|
|
@ -375,4 +374,5 @@ struct TritonEnvironment: TritonEnvironmentProtocol {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ struct TritonScene: Scene {
|
|||
#endif
|
||||
.environment(makeAccountUpdateService())
|
||||
.handlesExternalEvents(
|
||||
preferring: Set(arrayLiteral: "viewer"),
|
||||
allowing: Set(arrayLiteral: "*")
|
||||
preferring: ["viewer"],
|
||||
allowing: ["*"]
|
||||
)
|
||||
.onAppear {
|
||||
environment
|
||||
|
|
|
|||
|
|
@ -70,13 +70,11 @@ actor AccountUpdateRepository: AccountUpdateRepositoryProtocol {
|
|||
await fetchAccountInformation()
|
||||
}
|
||||
|
||||
for await isLoggedIn in authSessionService.observeLoginState() {
|
||||
if isLoggedIn {
|
||||
for await isLoggedIn in authSessionService.observeLoginState() where isLoggedIn {
|
||||
await fetchAccountInformation()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchAccountInformation() async {
|
||||
guard await authSessionService.isLoggedIn else { return }
|
||||
|
|
|
|||
|
|
@ -25,13 +25,11 @@ final class AuthAppViewModel {
|
|||
let currentState = await authSessionService.isLoggedIn
|
||||
isLoggedIn = currentState
|
||||
|
||||
for await loginState in authSessionService.observeLoginState() {
|
||||
if isLoggedIn != loginState {
|
||||
for await loginState in authSessionService.observeLoginState() where isLoggedIn != loginState {
|
||||
isLoggedIn = loginState
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
observationTask?.cancel()
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ final class AuthSessionServiceTests: XCTestCase {
|
|||
)
|
||||
}
|
||||
|
||||
func testObserveLoginStateYieldsCurrentState() async {
|
||||
func testObserveLoginStateYieldsCurrentState() async throws {
|
||||
// Given
|
||||
let initialState = await service.isLoggedIn
|
||||
|
||||
|
|
@ -97,9 +97,8 @@ final class AuthSessionServiceTests: XCTestCase {
|
|||
var iterator = stream.makeAsyncIterator()
|
||||
let firstValue = await iterator.next()
|
||||
|
||||
XCTAssertEqual(
|
||||
firstValue,
|
||||
false,
|
||||
XCTAssertFalse(
|
||||
try XCTUnwrap(firstValue),
|
||||
"It should yielded the first value correctly"
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,10 +185,10 @@ public struct SelectionToolbarItem<Option: Hashable & CaseIterable>: View {
|
|||
DropdownMenuView(
|
||||
options: options,
|
||||
selection: selection,
|
||||
itemLabel: itemLabel,
|
||||
label: {
|
||||
AnyView(style.makeLabel(helpText: helpText ?? style.defaultHelpText))
|
||||
}
|
||||
)
|
||||
itemLabel: itemLabel
|
||||
) {
|
||||
let helpText = helpText ?? style.defaultHelpText
|
||||
return AnyView(style.makeLabel(helpText: helpText))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,14 +78,16 @@ public struct TagListView: View {
|
|||
#Preview("Regular Tags") {
|
||||
TagListView(
|
||||
tags: ["swift", "ios", "macos"],
|
||||
helpText: { "Select \($0)" }
|
||||
) { _ in }
|
||||
helpText: { "Select \($0)" },
|
||||
action: { _ in }
|
||||
)
|
||||
}
|
||||
|
||||
#Preview("Remove Tags") {
|
||||
TagListView(
|
||||
tags: ["swift", "ios", "macos"],
|
||||
style: .remove,
|
||||
helpText: { "Remove \($0)" }
|
||||
) { _ in }
|
||||
helpText: { "Remove \($0)" },
|
||||
action: { _ in }
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import Testing
|
||||
@testable import FoundationExtensions
|
||||
|
||||
// swiftlint:disable file_length type_body_length
|
||||
|
||||
@Suite("ArrayContains Tests")
|
||||
struct ArrayContainsTests {
|
||||
|
||||
|
|
@ -535,3 +537,5 @@ struct ArrayContainsTests {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:enable file_length type_body_length
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct StringSlugTests {
|
|||
|
||||
// Then
|
||||
#expect(
|
||||
result == "",
|
||||
result.isEmpty,
|
||||
"It should handle empty string"
|
||||
)
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ struct StringSlugTests {
|
|||
|
||||
// Then
|
||||
#expect(
|
||||
result == "",
|
||||
result.isEmpty,
|
||||
"It should handle string with only whitespace"
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import Foundation
|
|||
import Testing
|
||||
@testable import FoundationExtensions
|
||||
|
||||
// swiftlint:disable file_length type_body_length
|
||||
|
||||
@Suite("StringWeblog Tests")
|
||||
struct StringWeblogTests {
|
||||
|
||||
|
|
@ -496,3 +498,5 @@ struct StringWeblogTests {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:enable file_length type_body_length
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct NowEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
networkServiceFactory: NowNetworkServiceFactoryProtocol,
|
||||
persistenceServiceFactory: NowPersistenceServiceFactoryProtocol,
|
||||
|
|
@ -113,4 +114,5 @@ struct NowEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@
|
|||
count: Int,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
let now = Now(
|
||||
listed: true,
|
||||
markdown: "Foobar \(i)",
|
||||
markdown: "Foobar \(index)",
|
||||
submitted: true,
|
||||
timestamp: 123_123 * Double(i),
|
||||
timestamp: 123_123 * Double(index),
|
||||
address: "otaviocc"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
func fetchNowPage(for address: String) async throws {}
|
||||
func updateNowPage(address: String, content: String, listed: Bool) async throws {}
|
||||
func fetchNowPage(
|
||||
for address: String
|
||||
) async throws {}
|
||||
|
||||
func updateNowPage(
|
||||
address: String,
|
||||
content: String,
|
||||
listed: Bool
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchNowPage() async throws {}
|
||||
func updateNowPage(address: String, content: String, isListed: Bool) async throws {}
|
||||
|
||||
func updateNowPage(
|
||||
address: String,
|
||||
content: String,
|
||||
isListed: Bool
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ import XCTest
|
|||
|
||||
final class NowTests: XCTestCase {
|
||||
|
||||
// swiftlint:disable:next empty_xctest_method
|
||||
func testExample() throws {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,4 @@ public struct CreateOrUpdatePasteRequest: Encodable, Sendable {
|
|||
let title: String
|
||||
let content: String
|
||||
let listed: Bool
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
init(
|
||||
title: String,
|
||||
content: String,
|
||||
listed: Bool
|
||||
) {
|
||||
self.title = title
|
||||
self.content = content
|
||||
self.listed = listed
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,4 @@ public struct CreatePURLRequest: Encodable, Sendable {
|
|||
let address: String
|
||||
let name: String
|
||||
let url: String
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
init(
|
||||
address: String,
|
||||
name: String,
|
||||
url: String
|
||||
) {
|
||||
self.address = address
|
||||
self.name = name
|
||||
self.url = url
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,4 @@ public struct UpdateNowPageRequest: Encodable, Sendable {
|
|||
|
||||
let content: String
|
||||
let listed: Int
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
init(
|
||||
content: String,
|
||||
listed: Int
|
||||
) {
|
||||
self.content = content
|
||||
self.listed = listed
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,4 @@ public struct UpdateWebpageRequest: Encodable, Sendable {
|
|||
|
||||
let content: String
|
||||
let publish: Bool
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
init(
|
||||
content: String,
|
||||
publish: Bool
|
||||
) {
|
||||
self.content = content
|
||||
self.publish = publish
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,4 @@ public struct UploadPictureRequest: Encodable, Sendable {
|
|||
// MARK: - Properties
|
||||
|
||||
let pic: String
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
init(
|
||||
pic: String
|
||||
) {
|
||||
self.pic = pic
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,22 +40,22 @@ struct AuthRequestFactoryTests {
|
|||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "client_id" }),
|
||||
queryItems.contains { $0.name == "client_id" },
|
||||
"It should include client_id parameter"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "scope" && $0.value == "everything" }),
|
||||
queryItems.contains { $0.name == "scope" && $0.value == "everything" },
|
||||
"It should include scope parameter with 'everything' value"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "response_type" && $0.value == "code" }),
|
||||
queryItems.contains { $0.name == "response_type" && $0.value == "code" },
|
||||
"It should include response_type parameter with 'code' value"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "redirect_uri" }),
|
||||
queryItems.contains { $0.name == "redirect_uri" },
|
||||
"It should include redirect_uri parameter"
|
||||
)
|
||||
}
|
||||
|
|
@ -82,27 +82,27 @@ struct AuthRequestFactoryTests {
|
|||
let queryItems = request.queryItems
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "client_id" }),
|
||||
queryItems.contains { $0.name == "client_id" },
|
||||
"It should include client_id query parameter"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "client_secret" }),
|
||||
queryItems.contains { $0.name == "client_secret" },
|
||||
"It should include client_secret query parameter"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "redirect_uri" }),
|
||||
queryItems.contains { $0.name == "redirect_uri" },
|
||||
"It should include redirect_uri query parameter"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "code" && $0.value == authCode }),
|
||||
queryItems.contains { $0.name == "code" && $0.value == authCode },
|
||||
"It should include code query parameter with provided auth code"
|
||||
)
|
||||
|
||||
#expect(
|
||||
queryItems.contains(where: { $0.name == "scope" && $0.value == "everything" }),
|
||||
queryItems.contains { $0.name == "scope" && $0.value == "everything" },
|
||||
"It should include scope query parameter"
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ struct PicsRequestFactoryTests {
|
|||
}
|
||||
|
||||
@Test("It should create picture edit request with empty tags array")
|
||||
func makeEditPictureRequest_withOnlyWithEmptyTagsArray_createsRequest() {
|
||||
func makeEditPictureRequest_withOnlyWithEmptyTagsArray_createsRequest() throws {
|
||||
// Given
|
||||
let address = "dave"
|
||||
let pictureID = "pic-456"
|
||||
|
|
@ -256,23 +256,26 @@ struct PicsRequestFactoryTests {
|
|||
"It should use PUT method"
|
||||
)
|
||||
|
||||
let body = try #require(request.body)
|
||||
let bodyTags = try #require(body.tags)
|
||||
|
||||
#expect(
|
||||
request.body?.tags == "",
|
||||
bodyTags.isEmpty == true,
|
||||
"It should include tags in request body"
|
||||
)
|
||||
|
||||
#expect(
|
||||
request.body?.caption == nil,
|
||||
body.caption == nil,
|
||||
"It should have nil caption when not provided"
|
||||
)
|
||||
|
||||
#expect(
|
||||
request.body?.alt == nil,
|
||||
body.alt == nil,
|
||||
"It should have nil alt text when not provided"
|
||||
)
|
||||
|
||||
#expect(
|
||||
request.body?.isHidden == nil,
|
||||
body.isHidden == nil,
|
||||
"It should have nil isHidden when not provided"
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ struct PURLsEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
networkServiceFactory: PURLsNetworkServiceFactoryProtocol,
|
||||
persistenceServiceFactory: PURLsPersistenceServiceFactoryProtocol,
|
||||
|
|
@ -123,4 +124,5 @@ struct PURLsEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,14 @@
|
|||
|
||||
private final class FakeClipboardService: ClipboardServiceProtocol {
|
||||
|
||||
func copy(_ string: String) {}
|
||||
func copy(_ data: Data, type: String) {}
|
||||
func copy(
|
||||
_ string: String
|
||||
) {}
|
||||
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@
|
|||
count: Int,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
let purl = PURL(
|
||||
name: "purl\(i)",
|
||||
url: URL(string: "http://subdomain\(i).otavio.lol")!,
|
||||
name: "purl\(index)",
|
||||
url: URL(string: "http://subdomain\(index).otavio.lol")!,
|
||||
address: "otaviocc"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
func fetchPURLs(for address: String) {}
|
||||
func addPURL(address: String, name: String, url: String) {}
|
||||
func deletePURL(address: String, name: String) async throws {}
|
||||
func fetchPURLs(
|
||||
for address: String
|
||||
) {}
|
||||
|
||||
func addPURL(
|
||||
address: String,
|
||||
name: String,
|
||||
url: String
|
||||
) {}
|
||||
|
||||
func deletePURL(
|
||||
address: String,
|
||||
name: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -37,8 +37,17 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchPURLs() {}
|
||||
func addPURL(address: String, name: String, url: String) {}
|
||||
func deletePURL(address: String, name: String) async throws {}
|
||||
|
||||
func addPURL(
|
||||
address: String,
|
||||
name: String,
|
||||
url: String
|
||||
) {}
|
||||
|
||||
func deletePURL(
|
||||
address: String,
|
||||
name: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ import XCTest
|
|||
|
||||
final class PURLsTests: XCTestCase {
|
||||
|
||||
// swiftlint:disable:next empty_xctest_method
|
||||
func testExample() throws {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ struct PastebinEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
networkServiceFactory: PastebinNetworkServiceFactoryProtocol,
|
||||
persistenceServiceFactory: PastebinPersistenceServiceFactoryProtocol,
|
||||
|
|
@ -123,4 +124,5 @@ struct PastebinEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,11 @@
|
|||
private final class FakeClipboardService: ClipboardServiceProtocol {
|
||||
|
||||
func copy(_ string: String) {}
|
||||
func copy(_ data: Data, type: String) {}
|
||||
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@
|
|||
count: Int,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
let paste = Paste(
|
||||
title: "paste\(i).md",
|
||||
title: "paste\(index).md",
|
||||
content: "hello, world!",
|
||||
timestamp: 123_123_123,
|
||||
address: "otaviocc",
|
||||
listed: i % 2 == 0
|
||||
listed: index % 2 == 0
|
||||
)
|
||||
|
||||
container.mainContext.insert(
|
||||
|
|
|
|||
|
|
@ -17,9 +17,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
func fetchPastes(for address: String) async throws {}
|
||||
func createOrUpdatePaste(address: String, title: String, content: String, listed: Bool) async throws {}
|
||||
func deletePaste(address: String, title: String) async throws {}
|
||||
func fetchPastes(
|
||||
for address: String
|
||||
) async throws {}
|
||||
|
||||
func createOrUpdatePaste(
|
||||
address: String,
|
||||
title: String,
|
||||
content: String,
|
||||
listed: Bool
|
||||
) async throws {}
|
||||
|
||||
func deletePaste(
|
||||
address: String,
|
||||
title: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -37,8 +37,18 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchPastes() async throws {}
|
||||
func createOrUpdatePaste(address: String, title: String, content: String, isListed: Bool) async throws {}
|
||||
func deletePaste(address: String, title: String) async throws {}
|
||||
|
||||
func createOrUpdatePaste(
|
||||
address: String,
|
||||
title: String,
|
||||
content: String,
|
||||
isListed: Bool
|
||||
) async throws {}
|
||||
|
||||
func deletePaste(
|
||||
address: String,
|
||||
title: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ import XCTest
|
|||
|
||||
final class PastebinTests: XCTestCase {
|
||||
|
||||
// swiftlint:disable:next empty_xctest_method
|
||||
func testExample() throws {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ struct PicsEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
networkServiceFactory: PicsNetworkServiceFactoryProtocol,
|
||||
persistenceServiceFactory: PicsPersistenceServiceFactoryProtocol,
|
||||
|
|
@ -119,4 +120,5 @@ struct PicsEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,14 @@
|
|||
|
||||
private final class FakeClipboardService: ClipboardServiceProtocol {
|
||||
|
||||
func copy(_ string: String) {}
|
||||
func copy(_ data: Data, type: String) {}
|
||||
func copy(
|
||||
_ string: String
|
||||
) {}
|
||||
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -12,8 +12,15 @@
|
|||
|
||||
// MARK: - Public
|
||||
|
||||
func fetchPictures(for address: String) async throws -> [PictureResponse] { [] }
|
||||
func deletePicture(address: String, pictureID: String) async throws {}
|
||||
func fetchPictures(
|
||||
for address: String
|
||||
) async throws -> [PictureResponse] { [] }
|
||||
|
||||
func deletePicture(
|
||||
address: String,
|
||||
pictureID: String
|
||||
) async throws {}
|
||||
|
||||
func updatePicture(
|
||||
address: String,
|
||||
pictureID: String,
|
||||
|
|
@ -21,6 +28,7 @@
|
|||
alt: String,
|
||||
tags: [String]
|
||||
) async throws {}
|
||||
|
||||
func uploadPicture(
|
||||
address: String,
|
||||
data: Data,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,12 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchPictures() async throws {}
|
||||
func deletePicture(address: String, pictureID: String) async throws {}
|
||||
|
||||
func deletePicture(
|
||||
address: String,
|
||||
pictureID: String
|
||||
) async throws {}
|
||||
|
||||
func updatePicture(
|
||||
address: String,
|
||||
pictureID: String,
|
||||
|
|
@ -47,6 +52,7 @@
|
|||
alt: String,
|
||||
tags: [String]
|
||||
) async throws {}
|
||||
|
||||
func uploadPicture(
|
||||
address: String,
|
||||
data: Data,
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
count: Int = 3,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
SomePicture.makePicture(
|
||||
created: Double(i * i),
|
||||
created: Double(index * index),
|
||||
in: container
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,12 +98,13 @@ struct EditPictureView: View {
|
|||
if !viewModel.suggestedTags.isEmpty {
|
||||
TagListView(
|
||||
tags: viewModel.suggestedTags,
|
||||
helpText: { "Add existing tag '\($0)'" }
|
||||
) { tag in
|
||||
helpText: { "Add existing tag '\($0)'" },
|
||||
action: { tag in
|
||||
withAnimation {
|
||||
viewModel.addTag(tag)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,12 +114,13 @@ struct EditPictureView: View {
|
|||
TagListView(
|
||||
tags: viewModel.tags,
|
||||
style: .remove,
|
||||
helpText: { "Remove tag '\($0)'" }
|
||||
) { tag in
|
||||
helpText: { "Remove tag '\($0)'" },
|
||||
action: { tag in
|
||||
withAnimation {
|
||||
viewModel.removeTag(tag)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ struct PicturesListView: View {
|
|||
_pictures = .init(viewModel.fetchDescriptor())
|
||||
}
|
||||
|
||||
// MARK; - Public
|
||||
// MARK: - Public
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
|
|
|
|||
|
|
@ -209,12 +209,13 @@ struct UploadView: View {
|
|||
if !viewModel.suggestedTags.isEmpty {
|
||||
TagListView(
|
||||
tags: viewModel.suggestedTags,
|
||||
helpText: { "Add existing tag '\($0)'" }
|
||||
) { tag in
|
||||
helpText: { "Add existing tag '\($0)'" },
|
||||
action: { tag in
|
||||
withAnimation(.easeInOut(duration: 0.2)) {
|
||||
viewModel.addTag(tag)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,12 +225,13 @@ struct UploadView: View {
|
|||
TagListView(
|
||||
tags: viewModel.tags,
|
||||
style: .remove,
|
||||
helpText: { "Remove tag '\($0)'" }
|
||||
) { tag in
|
||||
helpText: { "Remove tag '\($0)'" },
|
||||
action: { tag in
|
||||
withAnimation(.easeInOut(duration: 0.2)) {
|
||||
viewModel.removeTag(tag)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ struct StatusEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
repositoryFactory: StatusRepositoryFactoryProtocol,
|
||||
networkServiceFactory: StatusNetworkServiceFactoryProtocol,
|
||||
|
|
@ -120,4 +121,5 @@ struct StatusEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,14 @@
|
|||
|
||||
private final class FakeClipboardService: ClipboardServiceProtocol {
|
||||
|
||||
func copy(_ string: String) {}
|
||||
func copy(_ data: Data, type: String) {}
|
||||
func copy(
|
||||
_ string: String
|
||||
) {}
|
||||
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@
|
|||
count: Int,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
let status = Status(
|
||||
username: "user\(i)",
|
||||
statusID: "(i)",
|
||||
timestamp: Double(i),
|
||||
username: "user\(index)",
|
||||
statusID: "(index)",
|
||||
timestamp: Double(index),
|
||||
icon: "🤣",
|
||||
content: "Nulla purus urna, bibendum nec purus."
|
||||
)
|
||||
|
|
|
|||
|
|
@ -45,9 +45,10 @@ public struct StatusApp: View {
|
|||
ToolbarItemGroup {
|
||||
SelectionToolbarItem(
|
||||
options: StatusListFilter.allCases,
|
||||
selection: $filter,
|
||||
itemLabel: { $0.localizedTitle }
|
||||
)
|
||||
selection: $filter
|
||||
) { label in
|
||||
label.localizedTitle
|
||||
}
|
||||
.selectionToolbarItemStyle(FilterSelectionToolbarItemStyle())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,13 @@ struct ClipboardService: ClipboardServiceProtocol {
|
|||
service.copy(string)
|
||||
}
|
||||
|
||||
func copy(_ data: Data, type: String) {
|
||||
service.copy(data, type: type)
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {
|
||||
service.copy(
|
||||
data,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
)
|
||||
}
|
||||
|
||||
func copy(_ data: Data, type: String) {
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {
|
||||
NSPasteboard
|
||||
.general
|
||||
.clearContents()
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ struct WeblogEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
networkServiceFactory: WeblogNetworkServiceFactoryProtocol,
|
||||
persistenceServiceFactory: WeblogPersistenceServiceFactoryProtocol,
|
||||
|
|
@ -119,4 +120,5 @@ struct WeblogEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,14 @@
|
|||
|
||||
private final class FakeClipboardService: ClipboardServiceProtocol {
|
||||
|
||||
func copy(_ string: String) {}
|
||||
func copy(_ data: Data, type: String) {}
|
||||
func copy(
|
||||
_ string: String
|
||||
) {}
|
||||
|
||||
func copy(
|
||||
_ data: Data,
|
||||
type: String
|
||||
) {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@
|
|||
}
|
||||
|
||||
static func makeEntryResponses(count: Int = 5) -> [EntryResponse] {
|
||||
(0..<count).map { i in
|
||||
(0..<count).map { index in
|
||||
makeEntryResponse(
|
||||
id: "entry-\(i)",
|
||||
location: "test-entry-\(i)",
|
||||
date: Double(1_700_000_000 + (i * 86400)),
|
||||
status: i % 3 == 0 ? "draft" : "published",
|
||||
title: "Test Entry \(i)",
|
||||
body: "Content for test entry \(i)"
|
||||
id: "entry-\(index)",
|
||||
location: "test-entry-\(index)",
|
||||
date: Double(1_700_000_000 + (index * 86400)),
|
||||
status: index % 3 == 0 ? "draft" : "published",
|
||||
title: "Test Entry \(index)",
|
||||
body: "Content for test entry \(index)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
count: Int,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
let entry = WeblogEntry(
|
||||
id: "entry-\(i)",
|
||||
title: "Test Entry \(i)",
|
||||
body: "This is the body for test entry \(i). Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
date: Double(1_700_000_000 + (i * 86400)),
|
||||
status: i % 3 == 0 ? "draft" : "published",
|
||||
location: "test-entry-\(i)",
|
||||
id: "entry-\(index)",
|
||||
title: "Test Entry \(index)",
|
||||
body: "This is the body for test entry \(index). Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
date: Double(1_700_000_000 + (index * 86400)),
|
||||
status: index % 3 == 0 ? "draft" : "published",
|
||||
location: "test-entry-\(index)",
|
||||
address: "otaviocc"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,16 @@
|
|||
|
||||
// MARK: - Public
|
||||
|
||||
func fetchWeblogEntry(for address: String, entryID: String) async throws -> EntryResponse {
|
||||
func fetchWeblogEntry(
|
||||
for address: String,
|
||||
entryID: String
|
||||
) async throws -> EntryResponse {
|
||||
EntryResponseMother.makeEntryResponse()
|
||||
}
|
||||
|
||||
func fetchWeblogEntries(for address: String) async throws -> [EntryResponse] {
|
||||
func fetchWeblogEntries(
|
||||
for address: String
|
||||
) async throws -> [EntryResponse] {
|
||||
EntryResponseMother.makeEntryResponses(count: 2)
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +46,10 @@
|
|||
EntryResponseMother.makeEntryResponse()
|
||||
}
|
||||
|
||||
func deleteWeblogEntry(address: String, entryID: String) async throws {}
|
||||
func deleteWeblogEntry(
|
||||
address: String,
|
||||
entryID: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -39,7 +39,11 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchEntries() async throws {}
|
||||
func deleteEntry(address: String, entryID: String) async throws {}
|
||||
|
||||
func deleteEntry(
|
||||
address: String,
|
||||
entryID: String
|
||||
) async throws {}
|
||||
|
||||
func createOrUpdateEntry(
|
||||
address: String,
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ struct EditorView: View {
|
|||
}
|
||||
|
||||
@ViewBuilder
|
||||
// swiftlint:disable:next function_body_length
|
||||
private func makeSidebarView() -> some View {
|
||||
Grid(alignment: .leading, horizontalSpacing: 16, verticalSpacing: 16) {
|
||||
GridRow(alignment: .firstTextBaseline) {
|
||||
|
|
@ -146,12 +147,13 @@ struct EditorView: View {
|
|||
if !viewModel.suggestedTags.isEmpty {
|
||||
TagListView(
|
||||
tags: viewModel.suggestedTags,
|
||||
helpText: { "Add existing tag '\($0)'" }
|
||||
) { tag in
|
||||
helpText: { "Add existing tag '\($0)'" },
|
||||
action: { tag in
|
||||
withAnimation {
|
||||
viewModel.addTag(tag)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,12 +172,13 @@ struct EditorView: View {
|
|||
TagListView(
|
||||
tags: viewModel.tags,
|
||||
style: .remove,
|
||||
helpText: { "Remove tag '\($0)'" }
|
||||
) { tag in
|
||||
helpText: { "Remove tag '\($0)'" },
|
||||
action: { tag in
|
||||
withAnimation {
|
||||
viewModel.removeTag(tag)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ struct WeblogEntriesListView: View {
|
|||
_entries = .init(viewModel.fetchDescriptor())
|
||||
}
|
||||
|
||||
// MARK; - Public
|
||||
// MARK: - Public
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct WebpageEnvironment {
|
|||
)
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
init(
|
||||
networkServiceFactory: WebpageNetworkServiceFactoryProtocol,
|
||||
persistenceServiceFactory: WebpagePersistenceServiceFactoryProtocol,
|
||||
|
|
@ -112,4 +113,5 @@ struct WebpageEnvironment {
|
|||
)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable function_body_length
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@
|
|||
count: Int,
|
||||
in container: ModelContainer
|
||||
) {
|
||||
for i in 0..<count {
|
||||
for index in 0..<count {
|
||||
let page = Webpage(
|
||||
address: "otaviocc",
|
||||
markdown: "Foobar \(i)",
|
||||
timestamp: 123_123 * Double(i)
|
||||
markdown: "Foobar \(index)",
|
||||
timestamp: 123_123 * Double(index)
|
||||
)
|
||||
|
||||
container.mainContext.insert(
|
||||
|
|
|
|||
|
|
@ -17,8 +17,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
func fetchWebpage(for address: String) async throws {}
|
||||
func updateWebpage(address: String, content: String) async throws {}
|
||||
func fetchWebpage(
|
||||
for address: String
|
||||
) async throws {}
|
||||
|
||||
func updateWebpage(
|
||||
address: String,
|
||||
content: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -37,7 +37,11 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchWebpage() async throws {}
|
||||
func updateWebpage(address: String, content: String) async throws {}
|
||||
|
||||
func updateWebpage(
|
||||
address: String,
|
||||
content: String
|
||||
) async throws {}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ import XCTest
|
|||
|
||||
final class WebpageTests: XCTestCase {
|
||||
|
||||
// swiftlint:disable:next empty_xctest_method
|
||||
func testExample() throws {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue