Skip to content

Commit

Permalink
Adding Tests (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
leogdion authored Jan 3, 2025
1 parent 2b0ce35 commit 4dd2167
Show file tree
Hide file tree
Showing 26 changed files with 657 additions and 130 deletions.
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ let package = Package(
]
),
.testTarget(
name: "PackageDSLKitTests"
name: "PackageDSLKitTests",
dependencies: ["PackageDSLKit"]
)
]
)
Expand Down
8 changes: 4 additions & 4 deletions Sources/PackageDSLKit/Component.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
// OTHER DEALINGS IN THE SOFTWARE.
//

internal struct Component: Sendable, Hashable, Codable {
internal let name: String
internal let inheritedTypes: [String]
internal let properties: [String: Property]
public struct Component: Sendable, Hashable, Codable {
public let name: String
public let inheritedTypes: [String]
public let properties: [String: Property]
}
15 changes: 11 additions & 4 deletions Sources/PackageDSLKit/ComponentWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,18 @@

import SwiftSyntax

internal struct ComponentWriter: Sendable, Hashable, Codable {
private let propertyWriter = PropertyWriter()
internal func node(from component: Component) -> StructDeclSyntax {
public struct ComponentWriter: Sendable, StructureWriter {
private let propertyWriter: @Sendable (Property) -> VariableDeclSyntax

public init(
propertyWriter: @escaping @Sendable (Property) -> VariableDeclSyntax = PropertyWriter.node

Check warning on line 36 in Sources/PackageDSLKit/ComponentWriter.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/ComponentWriter.swift#L36

Added line #L36 was not covered by tests
) {
self.propertyWriter = propertyWriter
}

public func node(from component: Component) -> StructDeclSyntax {
let memberBlockList = MemberBlockItemListSyntax(
component.properties.values.map(propertyWriter.node(from:)).map {
component.properties.values.map(propertyWriter).map {
MemberBlockItemSyntax(decl: $0)
}
)
Expand Down
31 changes: 29 additions & 2 deletions Sources/PackageDSLKit/Dependency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,45 @@ public struct Dependency: TypeSource {
public init(rawValue: Int) {
self.rawValue = rawValue
}
public init?(strings: [String]) {
internal struct InvalidValueError: Error {
internal init?(invalidCount: Int) {
guard invalidCount != 0 else {
return nil
}
assert(invalidCount > 0)
self.invalidCount = invalidCount
}

internal init?(valuesCount: Int, indiciesCount: Int) {
self.init(invalidCount: indiciesCount - valuesCount)
}

internal let invalidCount: Int
}
internal init?(stringsThrows strings: [String]) throws(InvalidValueError) {
let indicies = strings.map {
Self.strings.firstIndex(of: $0)
}
let rawValues = indicies.compactMap(\.self).map { $0 + 1 }
if rawValues.isEmpty {
return nil
}
assert(rawValues.count == indicies.count)
if let error = InvalidValueError(valuesCount: rawValues.count, indiciesCount: indicies.count)
{
assert(error.invalidCount > 0)
throw error
}
let rawValue = rawValues.reduce(0) { $0 + $1 }
self.init(rawValue: rawValue)
}
public init?(strings: [String]) {
do {
try self.init(stringsThrows: strings)
} catch {
assertionFailure("Invalid Values Passed: \(error.invalidCount)")
return nil
}
}

Check warning on line 81 in Sources/PackageDSLKit/Dependency.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/Dependency.swift#L74-L81

Added lines #L74 - L81 were not covered by tests

internal func asInheritedTypes() -> [String] {
rawValue.powerOfTwoExponents().map { Self.strings[$0] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,74 @@
//

import Foundation
import PackageDSLKit

@available(*, deprecated, message: "Migrate to separate protocol.")
extension FileManager {
internal func swiftVersion(from directoryURL: URL) -> SwiftVersion? {
extension FileManager: PackageFilesInterface {
public var currentDirectoryURL: URL {
URL(fileURLWithPath: currentDirectoryPath)
}

Check warning on line 35 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L33-L35

Added lines #L33 - L35 were not covered by tests

private func readDirectoryContents(at path: String, fileExtension: String = "swift") throws
-> [String]
{
var contents: [String] = []
let items = try contentsOfDirectory(atPath: path)

// Process subdirectories (post-order)
for item in items {
let itemPath = (path as NSString).appendingPathComponent(item)
var isDirectory: ObjCBool = false
let fileExists = fileExists(atPath: itemPath, isDirectory: &isDirectory)

if fileExists && isDirectory.boolValue {
contents += try readDirectoryContents(at: itemPath, fileExtension: fileExtension)
}
}

// Process files
for item in items where item.hasSuffix(".\(fileExtension)") {
let itemPath = (path as NSString).appendingPathComponent(item)

let fileContents = try String(contentsOfFile: itemPath, encoding: .utf8)
contents.append(fileContents)
}

return contents
}

Check warning on line 63 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L39-L63

Added lines #L39 - L63 were not covered by tests
public func writePackageSwiftFile(
swiftVersion: SwiftVersion,
from dslSourcesURL: URL,
to pathURL: URL
) throws {
let contents = try self.readDirectoryContents(
at: dslSourcesURL.path(),
fileExtension: "swift"
)

let packageFileURL = pathURL.appendingPathComponent("Package.swift")
let strings =
[
"// swift-tools-version: \(swiftVersion)",
SupportCodeBlock.syntaxNode.trimmedDescription,
] + contents
let data = Data(strings.joined(separator: "\n").utf8)
self.createFile(atPath: packageFileURL.path(), contents: data)
// TODO: log error if file creation fails
}

Check warning on line 83 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L68-L83

Added lines #L68 - L83 were not covered by tests

public func createDirectory(at url: URL, withIntermediateDirectories createIntermediates: Bool)
throws
{
try self.createDirectory(
at: url,
withIntermediateDirectories: createIntermediates,
attributes: nil
)
}

Check warning on line 93 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L87-L93

Added lines #L87 - L93 were not covered by tests

public func createFile(at url: URL, text: String) {
self.createFile(atPath: url.path(), contents: Data(text.utf8))
}
public func swiftVersion(from directoryURL: URL) -> SwiftVersion? {
let swiftVersionURL = directoryURL.appending(component: ".swift-version")
let packageSwiftURL = directoryURL.appending(component: "Package.swift")

Expand All @@ -53,7 +116,7 @@ extension FileManager {

return .readFrom(packageSwiftFileURL: packageSwiftURL)
}

Check warning on line 118 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L95-L118

Added lines #L95 - L118 were not covered by tests
internal func createTargetSourceAt(
public func createTargetSourceAt(
_ pathURL: URL, productName: String, _ productType: ProductType
) throws {
let sourcesDirURL = pathURL.appendingPathComponent("Sources/\(productName)")
Expand Down Expand Up @@ -82,27 +145,24 @@ extension FileManager {
contents: Data(sourceCode.utf8)
)
}

Check warning on line 147 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L121-L147

Added lines #L121 - L147 were not covered by tests
internal func createTargetSourceAt(
_ pathURL: URL, productName: String, _ packageType: PackageType
public func createFileStructure(
forPackageType packageType: PackageType,
forProductName productName: String,
at pathURL: URL
) throws {
let productType: ProductType?

switch packageType {
case .empty:
productType = nil
case .library:
productType = .library
case .executable:
productType = .executable
guard packageType != .empty else {
return
}
assert(productType != nil, "Unknown package type \(packageType)")
guard let productType else {

try self.createTargetSourceAt(pathURL, productName: productName, packageType)

guard packageType == .library else {
return
}
try self.createTargetSourceAt(pathURL, productName: productName, productType)
}

fileprivate func createTestTargetAt(_ pathURL: URL, _ productName: String) throws {
try createTestTargetAt(pathURL, productName)
}
private func createTestTargetAt(_ pathURL: URL, _ productName: String) throws {
let testingDirURL = pathURL.appendingPathComponent("Tests/\(productName)Tests")
try self.createDirectory(at: testingDirURL, withIntermediateDirectories: true)

Expand All @@ -117,68 +177,23 @@ extension FileManager {
"""
self.createFile(atPath: testFileURL.path(), contents: Data(testCode.utf8))
}

Check warning on line 179 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L152-L179

Added lines #L152 - L179 were not covered by tests

internal func createFileStructure(
forPackageType packageType: PackageType,
forProductName productName: String,
at pathURL: URL
) throws {
guard packageType != .empty else {
return
}

try self.createTargetSourceAt(pathURL, productName: productName, packageType)

guard packageType == .library else {
return
}

try createTestTargetAt(pathURL, productName)
}
internal func writePackageSwiftFile(
swiftVersion: SwiftVersion,
from dslSourcesURL: URL,
to pathURL: URL
private func createTargetSourceAt(
_ pathURL: URL, productName: String, _ packageType: PackageType
) throws {
let contents = try self.readDirectoryContents(
at: dslSourcesURL.path(),
fileExtension: "swift"
)

let packageFileURL = pathURL.appendingPathComponent("Package.swift")
let strings =
[
"// swift-tools-version: \(swiftVersion)",
SupportCodeBlock.syntaxNode.trimmedDescription,
] + contents
let data = Data(strings.joined(separator: "\n").utf8)
self.createFile(atPath: packageFileURL.path(), contents: data)
}
internal func readDirectoryContents(at path: String, fileExtension: String = "swift") throws
-> [String]
{
var contents: [String] = []
let items = try contentsOfDirectory(atPath: path)

// Process subdirectories (post-order)
for item in items {
let itemPath = (path as NSString).appendingPathComponent(item)
var isDirectory: ObjCBool = false
fileExists(atPath: itemPath, isDirectory: &isDirectory)
let productType: ProductType?

if isDirectory.boolValue {
contents += try readDirectoryContents(at: itemPath, fileExtension: fileExtension)
}
switch packageType {
case .empty:
productType = nil
case .library:
productType = .library
case .executable:
productType = .executable
}

// Process files
for item in items where item.hasSuffix(".\(fileExtension)") {
let itemPath = (path as NSString).appendingPathComponent(item)

let fileContents = try String(contentsOfFile: itemPath, encoding: .utf8)
contents.append(fileContents)
assert(productType != nil, "Unknown package type \(packageType)")
guard let productType else {
return
}

return contents
try self.createTargetSourceAt(pathURL, productName: productName, productType)
}

Check warning on line 198 in Sources/PackageDSLKit/FileManager.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/FileManager.swift#L182-L198

Added lines #L182 - L198 were not covered by tests
}
34 changes: 34 additions & 0 deletions Sources/PackageDSLKit/IndexCodeWriter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// IndexCodeWriter.swift
// PackageDSLKit
//
// Created by Leo Dion.
// Copyright © 2025 BrightDigit.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

import SwiftSyntax

public protocol IndexCodeWriter: Sendable {
func writeIndex(_ index: Index) throws(PackageDSLError) -> String
}
51 changes: 51 additions & 0 deletions Sources/PackageDSLKit/PackageFiles.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// PackageFiles.swift
// PackageDSLKit
//
// Created by Leo Dion.
// Copyright © 2025 BrightDigit.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

import Foundation

public struct PackageFiles: PackageFilesFactory {
public static let `default`: PackageFilesFactory = PackageFiles()

private static let defaultTypes:
[PackageFilesInterfaceType: @Sendable () -> any PackageFilesInterface] = [
.fileManager: { FileManager.default }

Check warning on line 37 in Sources/PackageDSLKit/PackageFiles.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/PackageFiles.swift#L37

Added line #L37 was not covered by tests
]

private let types: [PackageFilesInterfaceType: @Sendable () -> any PackageFilesInterface]

internal init(
types: [PackageFilesInterfaceType: @Sendable () -> any PackageFilesInterface]? = nil
) {
self.types = types ?? Self.defaultTypes
}

Check warning on line 46 in Sources/PackageDSLKit/PackageFiles.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/PackageFiles.swift#L44-L46

Added lines #L44 - L46 were not covered by tests

public func interface(for type: PackageFilesInterfaceType) -> any PackageFilesInterface {
self.types[type]!()
}

Check warning on line 50 in Sources/PackageDSLKit/PackageFiles.swift

View check run for this annotation

Codecov / codecov/patch

Sources/PackageDSLKit/PackageFiles.swift#L48-L50

Added lines #L48 - L50 were not covered by tests
}
Loading

0 comments on commit 4dd2167

Please sign in to comment.