Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
64985df
add ability to run PDF generation via Docset API
dpvreony Apr 6, 2023
a7c00f0
refactor build to use exec helper
dpvreony Apr 6, 2023
a432fe1
rename pdf variable
dpvreony Apr 6, 2023
7a86b85
Merge branch 'dotnet:main' into gen-pdf-via-docascodeapp-lib
dpvreony Apr 6, 2023
e684cce
Merge branch 'dotnet:main' into gen-pdf-via-docascodeapp-lib
dpvreony Apr 17, 2023
236cb98
Merge branch 'dotnet:main' into gen-pdf-via-docascodeapp-lib
dpvreony Apr 19, 2023
e1f7ec8
Merge branch 'dotnet:main' into gen-pdf-via-docascodeapp-lib
dpvreony Jun 28, 2023
59a4197
remove method groups
dpvreony Jul 3, 2023
2938e01
prep for pdf unit tests
dpvreony Jul 3, 2023
aee3920
Update DocsetTest.cs
dpvreony Jul 4, 2023
2683e9d
Update DocsetTest.cs
dpvreony Jul 4, 2023
cba3e14
log issues hidden by templates not resolving
dpvreony Jul 4, 2023
4517977
housekeeping on tests
dpvreony Jul 5, 2023
ede880a
Merge remote-tracking branch 'upstream/main' into gen-pdf-via-docasco…
dpvreony Jul 5, 2023
fdbf4d8
remove snapshot test
dpvreony Jul 5, 2023
036cd7c
restore missing docset fact
dpvreony Jul 6, 2023
d69e67f
update template bundle error message
dpvreony Jul 6, 2023
c48a932
split pdf docset tests
dpvreony Jul 10, 2023
d9aa393
limit pdf tests to windows
dpvreony Jul 11, 2023
f383fc6
Merge remote-tracking branch 'upstream/main' into gen-pdf-via-docasco…
dpvreony Jul 11, 2023
a5cb09b
Merge remote-tracking branch 'upstream/main' into gen-pdf-via-docasco…
dpvreony Jul 17, 2023
cb07551
tweak counts on a couple of tests with new log event
dpvreony Jul 17, 2023
a33973d
fix last few tests around log counts
dpvreony Jul 17, 2023
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
52 changes: 50 additions & 2 deletions src/Microsoft.DocAsCode.App/Docset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,44 @@ public static Task Build(string configPath)
/// <param name="options">The build options.</param>
/// <returns>A task to await for build completion.</returns>
public static Task Build(string configPath, BuildOptions options)
{
return Exec<BuildJsonConfig>(
configPath,
options,
"build",
(config, exeOptions, configDirectory, outputDirectory) => RunBuild.Exec(config, exeOptions, configDirectory, outputDirectory));
}

/// <summary>
/// Builds a pdf specified by docfx.json config.
/// </summary>
/// <param name="configPath">The path to docfx.json config file.</param>
/// <returns>A task to await for build completion.</returns>
public static Task Pdf(string configPath)
{
return Pdf(configPath, new());
}

/// <summary>
/// Builds a pdf specified by docfx.json config.
/// </summary>
/// <param name="configPath">The path to docfx.json config file.</param>
/// <param name="options">The build options.</param>
/// <returns>A task to await for build completion.</returns>
public static Task Pdf(string configPath, BuildOptions options)
{
return Exec<PdfJsonConfig>(
configPath,
options,
"pdf",
(config, exeOptions, configDirectory, outputDirectory) => RunPdf.Exec(config, exeOptions, configDirectory, outputDirectory));
}

private static Task Exec<TConfig>(
string configPath,
BuildOptions options,
string elementKey,
Action<TConfig, BuildOptions, string, string> execAction)
{
var consoleLogListener = new ConsoleLogListener();
Logger.RegisterListener(consoleLogListener);
Expand All @@ -37,9 +75,19 @@ public static Task Build(string configPath, BuildOptions options)
{
var configDirectory = Path.GetDirectoryName(Path.GetFullPath(configPath));

var defaultSerializer = JsonUtility.DefaultSerializer.Value;

var config = JObject.Parse(File.ReadAllText(configPath));
if (config.TryGetValue("build", out var value))
RunBuild.Exec(value.ToObject<BuildJsonConfig>(JsonUtility.DefaultSerializer.Value), options, configDirectory);

if (config.TryGetValue(elementKey, out var value))
{
execAction(value.ToObject<TConfig>(defaultSerializer), options, configDirectory, null);
}
else
{
Logger.LogError($"Unable to find '{elementKey}' in '{configPath}'.");
}

return Task.CompletedTask;
}
finally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ internal ManifestItem Transform(InternalManifestItem item)
var templateBundle = _templateCollection[item.DocumentType];
if (templateBundle == null)
{
Logger.LogInfo($"No template bundle found for {item.DocumentType}, model will be ignored.");
return manifestItem;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public TemplateProcessor(ResourceFileReader resourceProvider, DocumentBuildConte
_resourceProvider = resourceProvider;
_maxParallelism = maxParallelism;
_templateCollection = new TemplateCollection(resourceProvider, context, maxParallelism);
if (_templateCollection.Count == 0)
{
Logger.LogWarning("No template bundles were found, no template will be applied to the documents. 1) Check your docfx.json 2) the templates subfolder exists inside your application folder or your docfx.json directory.");
}
Tokens = TemplateProcessorUtility.LoadTokens(resourceProvider) ?? new Dictionary<string, string>();
}

Expand Down
25 changes: 25 additions & 0 deletions test/docfx.Tests/Attributes/WindowsOnlyFactAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Runtime.InteropServices;
using Xunit;

namespace docfx.Tests.Attributes
Comment thread
yufeih marked this conversation as resolved.
{
/// <summary>
/// XUnit Fact attribute that skips the test if the OS is not Windows.
/// </summary>
/// <remarks>
/// Taken from https://github.com/dotnet/sdk/blob/a30e465a2e2ea4e2550f319a2dc088daaafe5649/src/Tests/Microsoft.NET.TestFramework/Attributes/WindowsOnlyFactAttribute.cs
/// </remarks>
public class WindowsOnlyFactAttribute : FactAttribute
{
public WindowsOnlyFactAttribute()
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
this.Skip = "This test requires Windows to run";
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
namespace Microsoft.DocAsCode.Tests;

[Collection("docfx STA")]
public class DocsetTest : TestBase
public class DocsetBuildTest : TestBase
{
private static async Task<Dictionary<string, Func<string>>> Build(Dictionary<string, string> files, [CallerMemberName] string testName = null)
{
var testDirectory = $"{nameof(DocsetTest)}/{testName}";
var testDirectory = $"{nameof(DocsetBuildTest)}/{testName}";
var outputDirectory = $"{testDirectory}/_site";

if (Directory.Exists(testDirectory))
Expand All @@ -35,6 +35,31 @@ private static async Task<Dictionary<string, Func<string>>> Build(Dictionary<str
f => new Func<string>(() => File.ReadAllText(f)));
}

private static async Task<Dictionary<string, Func<string>>> Pdf(Dictionary<string, string> files, [CallerMemberName] string testName = null)
{
var testDirectory = $"{nameof(DocsetBuildTest)}/{testName}";
var outputDirectory = $"{testDirectory}/_pdf";

if (Directory.Exists(testDirectory))
Directory.Delete(testDirectory, recursive: true);

Directory.CreateDirectory(testDirectory);
foreach (var (path, content) in files)
{
var targetPath = Path.Combine(testDirectory, path);
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));

File.WriteAllText(targetPath, content);
}

await Docset.Pdf($"{testDirectory}/docfx.json");

return Directory.GetFiles(outputDirectory, "*", SearchOption.AllDirectories)
.ToDictionary(
f => Path.GetRelativePath(outputDirectory, f),
f => new Func<string>(() => File.ReadAllText(f)));
}

[Fact]
public static async Task CustomLogo_Override_LogoFromTemplate()
{
Expand Down
199 changes: 199 additions & 0 deletions test/docfx.Tests/DocsetPdfTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using docfx.Tests.Attributes;
using Microsoft.DocAsCode.Tests.Common;

using Xunit;

namespace Microsoft.DocAsCode.Tests;

[Collection("docfx STA")]
public class DocsetPdfTest : TestBase
{
private static async Task<Dictionary<string, Func<string>>> Pdf(Dictionary<string, string> files, [CallerMemberName] string testName = null)
{
var testDirectory = $"{nameof(DocsetPdfTest)}/{testName}";
var outputDirectory = $"{testDirectory}/_pdf";

if (Directory.Exists(testDirectory))
Directory.Delete(testDirectory, recursive: true);

Directory.CreateDirectory(testDirectory);
foreach (var (path, content) in files)
{
var targetPath = Path.Combine(testDirectory, path);
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));

File.WriteAllText(targetPath, content);
}

await Docset.Pdf($"{testDirectory}/docfx.json");

return Directory.GetFiles(outputDirectory, "*", SearchOption.AllDirectories)
.ToDictionary(
f => Path.GetRelativePath(outputDirectory, f),
f => new Func<string>(() => File.ReadAllText(f)));
}

[WindowsOnlyFact]
public static async Task Pdf_Basic()
{
var outputs = await Pdf(new()
{
["docfx.json"] =
"""
{
"pdf": {
"content": [
{
"files": [
"**/**.md"
]
},
{
"files": "**/toc.yml"
}
],
"wkhtmltopdf": {
"additionalArguments": "--enable-local-file-access"
},
"dest": "_pdf"
}
}
""",
["pdf/toc.yml"] = "- name: Introduction\r\n href: intro.md\r\n- name: Another Page\r\n href: anotherpage.md\r\n",
["pdf/intro.md"] = "# Introduction\r\n\r\n",
["pdf/anotherpage.md"] = "# Another Page\r\n\r\n"
});

Assert.True(outputs.ContainsKey("Pdf_Basic_pdf.pdf"));
}

[WindowsOnlyFact]
public static async Task Pdf_With_Cover_Page()
{
var outputs = await Pdf(new()
{
["docfx.json"] =
"""
{
"pdf": {
"content": [
{
"files": [
"**/**.md"
]
},
{
"files": "**/toc.yml"
}
],
"wkhtmltopdf": {
"additionalArguments": "--enable-local-file-access"
},
"dest": "_pdf"
}
}
""",
["pdf/toc.yml"] = "- name: Introduction\r\n href: intro.md\r\n- name: Another Page\r\n href: anotherpage.md\r\n",
["pdf/cover.md"] = "# My Basic Cover Page\r\n\r\n",
["pdf/intro.md"] = "# Introduction\r\n\r\n",
["pdf/anotherpage.md"] = "# Another Page\r\n\r\n"
});

Assert.True(outputs.ContainsKey("Pdf_With_Cover_Page_pdf.pdf"));
}

[WindowsOnlyFact]
public static async Task Pdf_With_Global_Metadata_Files()
{
var outputs = await Pdf(new()
{
["docfx.json"] =
"""
{
"pdf": {
"content": [{ "files": [ "*.md" ] },{ "files": "toc.yml" }],
"dest": "_pdf",
"exportRawModel": true,
"globalMetadataFiles": ["projectMetadata1.json", "projectMetadata2.json"],
"globalMetadata": {
"meta1": "docfx.json",
"meta3": "docfx.json"
}
}
}
""",
["projectMetadata1.json"] =
"""
{
"meta1": "projectMetadata1.json",
"meta2": "projectMetadata2.json"
}
""",
["projectMetadata2.json"] =
"""
{
"meta2": "projectMetadata2.json"
}
""",
["toc.yml"] = "- name: Introduction\r\n href: intro.md\r\n- name: Another Page\r\n href: anotherpage.md\r\n",
["cover.md"] = "# My Basic Cover Page\r\n\r\n",
["intro.md"] = "# Introduction\r\n\r\n",
["anotherpage.md"] = "# Another Page\r\n\r\n"
});

Assert.True(outputs.ContainsKey("Pdf_With_Global_Metadata_Files.pdf"));
}

[WindowsOnlyFact]
public static async Task Pdf_With_File_Metadata_Files()
{
var outputs = await Pdf(new()
{
["docfx.json"] =
"""
{
"pdf": {
"content": [{ "files": [ "*.md" ] },{ "files": "toc.yml" }],
"dest": "_pdf",
"exportRawModel": true,
"fileMetadataFiles": ["fileMetadata1.json", "fileMetadata2.json"],
"fileMetadata": {
"meta1": {
"a.md": "docfx.json"
}
}
}
}
""",
["fileMetadata1.json"] =
"""
{
"meta1": {
"a.md": "fileMetadata1.json",
"b.md": "fileMetadata1.json"
}
}
""",
["fileMetadata2.json"] =
"""
{
"meta1": {
"b.md": "fileMetadata2.json"
}
}
""",
["a.md"] = "",
["b.md"] = "",
["toc.yml"] = "- name: Introduction\r\n href: intro.md\r\n- name: Another Page\r\n href: anotherpage.md\r\n",
["cover.md"] = "# My Basic Cover Page\r\n\r\n",
["intro.md"] = "# Introduction\r\n\r\n",
["anotherpage.md"] = "# Another Page\r\n\r\n"
});

Assert.True(outputs.ContainsKey("Pdf_With_File_Metadata_Files.pdf"));
}
}
8 changes: 2 additions & 6 deletions test/docfx.Tests/PdfTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using docfx.Tests.Attributes;
using Microsoft.DocAsCode.Tests.Common;
using Xunit;

Expand All @@ -10,11 +11,6 @@ namespace Microsoft.DocAsCode.Tests;
[Collection("docfx STA")]
public class PdfTest : TestBase
{
class PdfFact : FactAttribute
{
public override string Skip => OperatingSystem.IsWindows() ? null : "Skip PDF test on non-windows platforms";
}

private static async Task<string> Build(Dictionary<string, string> files, [CallerMemberName] string testName = null)
{
var testDirectory = $"{nameof(PdfTest)}/{testName}";
Expand All @@ -35,7 +31,7 @@ private static async Task<string> Build(Dictionary<string, string> files, [Calle
return outputDirectory;
}

[PdfFact]
[WindowsOnlyFact]
public static async Task BuildPdf_GeneratesPdfFile()
{
var outputDirectory = await Build(new()
Expand Down