Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/hexcode/Commands/Hexcode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct Hexcode: AsyncParsableCommand {
by their hexadecimal codes.
""",
usage: "hexcode <color-hex> [--directory <directory>]",
version: "hexcode 0.2.0",
version: "hexcode 0.2.1",
subcommands: [
FindColor.self,
FindDuplicates.self,
Expand Down
16 changes: 13 additions & 3 deletions Sources/hexcode/HexcodeApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ final class HexcodeApp {
/// - directory: Optional custom directory from user input. Defaults to current directory.
/// - throws: All unhandled errors that can be thrown out to standard output.
func runFindColor(colorHex: String, in directory: String? = nil) async throws {
let directory = directory ?? fileManager.currentDirectoryPath
let directory = directory.map(expandTilde) ?? fileManager.currentDirectoryPath
let colorAssets = try await assetCollector.collectAssets(in: directory)
let foundColors = colorFinder.find(colorHex, in: colorAssets)

Expand All @@ -39,12 +39,11 @@ final class HexcodeApp {
foundColors.forEach { output($0) }
}


/// Entry point for the `find-duplicates` subcommand logic.
/// - Parameter directory: Optional custom directory from user input. Defaults to current directory.
/// - throws: All unhandled errors that can be thrown out to standard output.
func runFindDuplicates(in directory: String? = nil) async throws {
let directory = directory ?? fileManager.currentDirectoryPath
let directory = directory.map(expandTilde) ?? fileManager.currentDirectoryPath
let colorAssets = try await assetCollector.collectAssets(in: directory)
let foundDuplicates = colorFinder.findDuplicates(in: colorAssets)

Expand Down Expand Up @@ -72,3 +71,14 @@ final class HexcodeApp {
}
}
}

// MARK: - Private

extension HexcodeApp {
private func expandTilde(_ path: String) -> String {
path.replacingOccurrences(
of: "~",
with: fileManager.homeDirectoryForCurrentUser.relativePath
)
}
}
38 changes: 38 additions & 0 deletions Tests/hexcodeTests/HexcodeAppTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,25 @@ final class HexcodeAppTests: XCTestCase {
XCTAssertEqual(mocks.outputs, ["No \(blackHexStub) color found"])
}

func test_runFindColor_withTildeInPath_expandsTildaToFilePath() async throws {
// Given
let homeDir = "/home/dir"
let homeURL = try XCTUnwrap(URL(filePath: homeDir))
mocks.fileManager.results.homeDirectoryForCurrentUser = homeURL

// When
try await sut.runFindColor(colorHex: blackHexStub, in: "~/TestProject")


// Then
XCTAssertEqual(mocks.fileManager.calls, [
.getHomeDirectoryForCurrentUser
])
XCTAssertEqual(mocks.assetCollector.calls, [
.collectAssetsIn(directory: "\(homeDir)/TestProject")
])
}

// MARK: Test runFindDuplicates

func test_runFindDuplicates_whenSingleDuplicateFound_outputsDuplicateHexAndAssetNames() async throws {
Expand Down Expand Up @@ -226,6 +245,25 @@ final class HexcodeAppTests: XCTestCase {
"#FFFFFF text (Any, Light)",
])
}

func test_runFindDuplicates_withTildeInPath_expandsTildaToFilePath() async throws {
// Given
let homeDir = "/Users/user"
let homeURL = try XCTUnwrap(URL(string: homeDir))
mocks.fileManager.results.homeDirectoryForCurrentUser = homeURL

// When
try await sut.runFindDuplicates(in: "~/documents/project")


// Then
XCTAssertEqual(mocks.fileManager.calls, [
.getHomeDirectoryForCurrentUser
])
XCTAssertEqual(mocks.assetCollector.calls, [
.collectAssetsIn(directory: "\(homeDir)/documents/project")
])
}
}

// MARK: - Private
Expand Down
9 changes: 9 additions & 0 deletions Tests/hexcodeTests/Mocks/FileManagerMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ final class FileManagerMock: FileManager {
enum Call: Equatable {
case getCurrentDirectoryPath
case setCurrentDirectoryPath(String)
case getHomeDirectoryForCurrentUser
case fileExists(path: String, isDirectory: UnsafeMutablePointer<ObjCBool>?)
case contentsOfDirectory(path: String)
case contents(path: String)
}

struct CallResults {
var currentDirectoryPath: String = ""
var homeDirectoryForCurrentUser: URL = .init(filePath: "")
var fileExistsAtPath: [String: PathContent] = [:]
var contentsOfDirectory: [String: Result<[String], Error>] = [:]
var contentsAtPath: [String: Data] = [:]
Expand Down Expand Up @@ -60,6 +62,13 @@ extension FileManagerMock {
}
}

override var homeDirectoryForCurrentUser: URL {
get {
calls.append(.getHomeDirectoryForCurrentUser)
return results.homeDirectoryForCurrentUser
}
}

override func fileExists(atPath path: String, isDirectory: UnsafeMutablePointer<ObjCBool>?) -> Bool {
calls.append(.fileExists(path: path, isDirectory: isDirectory))
guard let pathContent = results.fileExistsAtPath[path] else { return false }
Expand Down