feat: Updates tests for html generation, adds some more documentation strings.
This commit is contained in:
@@ -6,14 +6,19 @@ import PlaybookClient
|
||||
|
||||
extension PandocClient.RunOptions {
|
||||
|
||||
/// Runs a pandoc conversion on the project generating the given file type.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - fileType: The file type to convert to.
|
||||
/// - environment: The environment variables.
|
||||
///
|
||||
/// - Returns: File path to the converted output file.
|
||||
func run(
|
||||
_ fileType: PandocClient.FileType,
|
||||
_ environment: [String: String]
|
||||
) async throws -> String {
|
||||
@Dependency(\.commandClient) var commandClient
|
||||
@Dependency(\.logger) var logger
|
||||
|
||||
// return try await commandClient.run(logging: loggingOptions, quiet: quiet, shell: shell) {
|
||||
let ensuredOptions = try await self.ensuredOptions(fileType)
|
||||
|
||||
let projectDirectory = self.projectDirectory ?? environment["PWD"]
|
||||
@@ -22,13 +27,12 @@ extension PandocClient.RunOptions {
|
||||
throw ProjectDirectoryNotSpecified()
|
||||
}
|
||||
|
||||
try await buildProject(fileType, projectDirectory, ensuredOptions)
|
||||
try await buildProject(projectDirectory, ensuredOptions)
|
||||
|
||||
let outputDirectory = self.outputDirectory ?? projectDirectory
|
||||
let outputPath = "\(outputDirectory)/\(ensuredOptions.ensuredExtensionFileName)"
|
||||
let outputPath = "\(outputDirectory)/\(ensuredOptions.ensuredFilename)"
|
||||
|
||||
let arguments = ensuredOptions.makeArguments(
|
||||
fileType: fileType,
|
||||
outputPath: outputPath,
|
||||
projectDirectory: projectDirectory
|
||||
)
|
||||
@@ -36,16 +40,13 @@ extension PandocClient.RunOptions {
|
||||
logger.debug("Pandoc arguments: \(arguments)")
|
||||
return try await runCommand(arguments, outputPath)
|
||||
|
||||
// return (arguments, outputPath)
|
||||
// }
|
||||
}
|
||||
|
||||
/// Runs a shell command with the given arguments, returning the passed in output path
|
||||
/// so the command can be chained, if needed.
|
||||
///
|
||||
@_spi(Internal)
|
||||
@discardableResult
|
||||
public func runCommand(
|
||||
func runCommand(
|
||||
_ arguments: [String],
|
||||
_ outputPath: String
|
||||
) async throws -> String {
|
||||
@@ -60,9 +61,7 @@ extension PandocClient.RunOptions {
|
||||
/// Build the project if necessary, before running the shell command that builds the final
|
||||
/// output file(s).
|
||||
///
|
||||
@_spi(Internal)
|
||||
public func buildProject(
|
||||
_ fileType: PandocClient.FileType,
|
||||
func buildProject(
|
||||
_ projectDirectory: String,
|
||||
_ ensuredOptions: EnsuredPandocOptions
|
||||
) async throws {
|
||||
@@ -87,11 +86,10 @@ extension PandocClient.RunOptions {
|
||||
|
||||
// Build latex file pre-html, so that we can properly convert the latex document
|
||||
// into an html document.
|
||||
if fileType == .html {
|
||||
if ensuredOptions.outputFileType == .html {
|
||||
logger.debug("Building latex, pre-html conversion...")
|
||||
let outputPath = "\(ensuredOptions.buildDirectory)/Report.tex"
|
||||
let outputPath = "\(ensuredOptions.buildDirectory)/\(EnsuredPandocOptions.latexFilename)"
|
||||
let arguments = ensuredOptions.preHtmlLatexOptions.makeArguments(
|
||||
fileType: .latex,
|
||||
outputPath: outputPath,
|
||||
projectDirectory: projectDirectory
|
||||
)
|
||||
@@ -99,6 +97,11 @@ extension PandocClient.RunOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the ensured/parsed options for a pandoc conversion.
|
||||
///
|
||||
/// - Parameter fileType: The file type we're converting to.
|
||||
///
|
||||
/// - Returns: The ensured options.
|
||||
func ensuredOptions(
|
||||
_ fileType: PandocClient.FileType
|
||||
) async throws -> EnsuredPandocOptions {
|
||||
@@ -117,6 +120,7 @@ extension PandocClient.RunOptions {
|
||||
}
|
||||
|
||||
extension PandocClient.FileType {
|
||||
/// Represents the appropriate file extension for a file type.
|
||||
var fileExtension: String {
|
||||
switch self {
|
||||
case .html: return "html"
|
||||
@@ -126,6 +130,10 @@ extension PandocClient.FileType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents pandoc options that get parsed based on the given run options, configuration, etc.
|
||||
///
|
||||
/// This set's potentially optional values into real values that are required for pandoc to run
|
||||
/// properly and convert files for the given file type conversion.
|
||||
@_spi(Internal)
|
||||
public struct EnsuredPandocOptions: Equatable, Sendable {
|
||||
public static let latexFilename = "Report.tex"
|
||||
@@ -138,7 +146,9 @@ public struct EnsuredPandocOptions: Equatable, Sendable {
|
||||
public let outputFileType: PandocClient.FileType
|
||||
public let pdfEngine: String?
|
||||
|
||||
public var ensuredExtensionFileName: String {
|
||||
/// Ensures the output filename includes the file extension, so that pandoc
|
||||
/// can properly convert the files.
|
||||
public var ensuredFilename: String {
|
||||
let extensionString = ".\(outputFileType.fileExtension)"
|
||||
|
||||
if !outputFileName.hasSuffix(extensionString) {
|
||||
@@ -147,7 +157,9 @@ public struct EnsuredPandocOptions: Equatable, Sendable {
|
||||
return outputFileName
|
||||
}
|
||||
|
||||
public var preHtmlLatexOptions: Self {
|
||||
/// Generates the options required for building the latex file that is needed
|
||||
/// to convert the project to an html output file.
|
||||
var preHtmlLatexOptions: Self {
|
||||
.init(
|
||||
buildDirectory: buildDirectory,
|
||||
extraOptions: extraOptions,
|
||||
@@ -159,14 +171,16 @@ public struct EnsuredPandocOptions: Equatable, Sendable {
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate arguments for the pandoc shell command based on the parsed options
|
||||
/// for a given conversion.
|
||||
///
|
||||
func makeArguments(
|
||||
fileType: PandocClient.FileType,
|
||||
outputPath: String,
|
||||
projectDirectory: String
|
||||
) -> [String] {
|
||||
var arguments = [PandocClient.Constants.pandocCommand]
|
||||
|
||||
if fileType != .html {
|
||||
if outputFileType != .html {
|
||||
arguments += includeInHeader.map {
|
||||
"--include-in-header=\(projectDirectory)/\(buildDirectory)/\($0)"
|
||||
}
|
||||
@@ -182,7 +196,7 @@ public struct EnsuredPandocOptions: Equatable, Sendable {
|
||||
arguments.append(contentsOf: extraOptions)
|
||||
}
|
||||
|
||||
if fileType != .html {
|
||||
if outputFileType != .html {
|
||||
arguments += files.map {
|
||||
"\(projectDirectory)/\(buildDirectory)/\($0)"
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@_spi(Internal) import ConfigurationClient
|
||||
@_spi(Internal) import PandocClient
|
||||
import PlaybookClient
|
||||
import Testing
|
||||
import TestSupport
|
||||
import Testing
|
||||
|
||||
@Suite("PandocClientTests")
|
||||
struct PandocClientTests: TestCase {
|
||||
@@ -13,12 +13,12 @@ struct PandocClientTests: TestCase {
|
||||
|
||||
static let expectedIncludeInHeaders = [
|
||||
"--include-in-header=/project/.build/head.tex",
|
||||
"--include-in-header=/project/.build/footer.tex"
|
||||
"--include-in-header=/project/.build/footer.tex",
|
||||
]
|
||||
|
||||
static let expectedFiles = [
|
||||
"/project/.build/Report.md",
|
||||
"/project/.build/Definitions.md"
|
||||
"/project/.build/Definitions.md",
|
||||
]
|
||||
|
||||
static var sharedRunOptions: PandocClient.RunOptions {
|
||||
@@ -49,7 +49,8 @@ struct PandocClientTests: TestCase {
|
||||
#expect(output == "\(Self.outputDirectory)/\(Self.defaultFileName).tex")
|
||||
|
||||
} assert: { output in
|
||||
let expected = ["pandoc"]
|
||||
let expected =
|
||||
["pandoc"]
|
||||
+ Self.expectedIncludeInHeaders
|
||||
+ ["--output=\(Self.outputDirectory)/\(Self.defaultFileName).tex"]
|
||||
+ Self.expectedFiles
|
||||
@@ -71,10 +72,11 @@ struct PandocClientTests: TestCase {
|
||||
#expect(output == "\(Self.outputDirectory)/\(Self.defaultFileName).html")
|
||||
|
||||
} assert: { output in
|
||||
let expected = ["pandoc"]
|
||||
+ Self.expectedIncludeInHeaders
|
||||
+ ["--output=\(Self.outputDirectory)/\(Self.defaultFileName).html"]
|
||||
+ Self.expectedFiles
|
||||
let expected = [
|
||||
"pandoc",
|
||||
"--output=\(Self.outputDirectory)/\(Self.defaultFileName).html",
|
||||
"\(Self.projectDirectory)/.build/Report.tex",
|
||||
]
|
||||
|
||||
#expect(output.arguments == expected)
|
||||
}
|
||||
@@ -83,7 +85,7 @@ struct PandocClientTests: TestCase {
|
||||
@Test(
|
||||
arguments: [
|
||||
nil,
|
||||
"lualatex"
|
||||
"lualatex",
|
||||
]
|
||||
)
|
||||
func generatePdf(pdfEngine: String?) async throws {
|
||||
@@ -94,11 +96,13 @@ struct PandocClientTests: TestCase {
|
||||
} run: {
|
||||
@Dependency(\.pandocClient) var pandocClient
|
||||
|
||||
let output = try await pandocClient.run.generatePdf(Self.sharedRunOptions, pdfEngine: pdfEngine)
|
||||
let output = try await pandocClient.run.generatePdf(
|
||||
Self.sharedRunOptions, pdfEngine: pdfEngine)
|
||||
#expect(output == "\(Self.outputDirectory)/\(Self.defaultFileName).pdf")
|
||||
|
||||
} assert: { output in
|
||||
let expected = ["pandoc"]
|
||||
let expected =
|
||||
["pandoc"]
|
||||
+ Self.expectedIncludeInHeaders
|
||||
+ ["--pdf-engine=\(pdfEngine ?? "xelatex")"]
|
||||
+ ["--output=\(Self.outputDirectory)/\(Self.defaultFileName).pdf"]
|
||||
@@ -147,10 +151,18 @@ struct TestPdfEngine: Sendable {
|
||||
static let testCases: [Self] = [
|
||||
.init(fileType: .html, expectedEngine: nil, configuration: .init(), defaults: .default),
|
||||
.init(fileType: .latex, expectedEngine: nil, configuration: .init(), defaults: .default),
|
||||
.init(fileType: .pdf(engine: "lualatex"), expectedEngine: "lualatex", configuration: .init(), defaults: .default),
|
||||
.init(fileType: .pdf(engine: nil), expectedEngine: "xelatex", configuration: .init(), defaults: .default),
|
||||
.init(fileType: .pdf(engine: nil), expectedEngine: "xelatex", configuration: .init(), defaults: .init()),
|
||||
.init(fileType: .pdf(engine: nil), expectedEngine: "xelatex", configuration: .init(generate: .default), defaults: .init())
|
||||
.init(
|
||||
fileType: .pdf(engine: "lualatex"), expectedEngine: "lualatex", configuration: .init(),
|
||||
defaults: .default),
|
||||
.init(
|
||||
fileType: .pdf(engine: nil), expectedEngine: "xelatex", configuration: .init(),
|
||||
defaults: .default),
|
||||
.init(
|
||||
fileType: .pdf(engine: nil), expectedEngine: "xelatex", configuration: .init(),
|
||||
defaults: .init()),
|
||||
.init(
|
||||
fileType: .pdf(engine: nil), expectedEngine: "xelatex",
|
||||
configuration: .init(generate: .default), defaults: .init()),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -174,19 +186,23 @@ struct TestParseFiles: Sendable {
|
||||
}
|
||||
|
||||
var parsedFiles: [String] {
|
||||
let runOptions = self.runOptions ?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug),
|
||||
projectDirectory: nil,
|
||||
quiet: true,
|
||||
shouldBuild: false
|
||||
)
|
||||
let runOptions =
|
||||
self.runOptions
|
||||
?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug),
|
||||
projectDirectory: nil,
|
||||
quiet: true,
|
||||
shouldBuild: false
|
||||
)
|
||||
|
||||
return runOptions.parseFiles(configuration.generate, defaults)
|
||||
}
|
||||
|
||||
static let testCases: [Self] = [
|
||||
.init(expectedFiles: ["Report.md", "Definitions.md"]),
|
||||
.init(expectedFiles: ["Report.md", "Definitions.md"], configuration: .init(generate: .default), defaults: .init()),
|
||||
.init(
|
||||
expectedFiles: ["Report.md", "Definitions.md"], configuration: .init(generate: .default),
|
||||
defaults: .init()),
|
||||
.init(expectedFiles: [], defaults: .init()),
|
||||
.init(
|
||||
expectedFiles: ["custom.md"],
|
||||
@@ -199,7 +215,7 @@ struct TestParseFiles: Sendable {
|
||||
quiet: true,
|
||||
shouldBuild: false
|
||||
)
|
||||
)
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -223,16 +239,20 @@ struct TestParseIncludeInHeaderFiles: Sendable {
|
||||
}
|
||||
|
||||
var parsedFiles: [String] {
|
||||
let runOptions = self.runOptions ?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
let runOptions =
|
||||
self.runOptions
|
||||
?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
|
||||
return runOptions.parseIncludeInHeader(configuration.generate, defaults)
|
||||
}
|
||||
|
||||
static let testCases: [Self] = [
|
||||
.init(expectedHeaderFiles: ["head.tex", "footer.tex"]),
|
||||
.init(expectedHeaderFiles: ["head.tex", "footer.tex"], configuration: .init(generate: .default), defaults: .init()),
|
||||
.init(
|
||||
expectedHeaderFiles: ["head.tex", "footer.tex"], configuration: .init(generate: .default),
|
||||
defaults: .init()),
|
||||
.init(expectedHeaderFiles: [], defaults: .init()),
|
||||
.init(
|
||||
expectedHeaderFiles: ["custom.tex"],
|
||||
@@ -242,7 +262,7 @@ struct TestParseIncludeInHeaderFiles: Sendable {
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug),
|
||||
includeInHeader: ["custom.tex"]
|
||||
)
|
||||
)
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -266,9 +286,11 @@ struct TestParseOutputFileName: Sendable {
|
||||
}
|
||||
|
||||
var parsedFileName: String {
|
||||
let runOptions = self.runOptions ?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
let runOptions =
|
||||
self.runOptions
|
||||
?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
|
||||
return runOptions.parseOutputFileName(configuration.generate, defaults)
|
||||
}
|
||||
@@ -285,7 +307,7 @@ struct TestParseOutputFileName: Sendable {
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug),
|
||||
outputFileName: "custom"
|
||||
)
|
||||
)
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -309,9 +331,11 @@ struct TestParseBuildDirectory: Sendable {
|
||||
}
|
||||
|
||||
var parsedBuildDirectory: String {
|
||||
let runOptions = self.runOptions ?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
let runOptions =
|
||||
self.runOptions
|
||||
?? PandocClient.RunOptions(
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
|
||||
return runOptions.parseBuildDirectory(configuration.generate, defaults)
|
||||
}
|
||||
@@ -328,6 +352,6 @@ struct TestParseBuildDirectory: Sendable {
|
||||
buildDirectory: "custom",
|
||||
loggingOptions: .init(commandName: "parseFiles", logLevel: .debug)
|
||||
)
|
||||
)
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user