-
-
Notifications
You must be signed in to change notification settings - Fork 5
dotnet: allow customizing resources in subclasses #400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
2c93d93
f8bd7e9
f1f7169
e8d8824
29505c9
4a187d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System.Reflection; | ||
|
||
namespace Cucumber.HtmlFormatter; | ||
|
||
/// <summary> | ||
/// Default implementation of IResourceProvider | ||
/// </summary> | ||
public class DefaultResourceProvider : IResourceProvider | ||
{ | ||
private const string TEMPLATE_RESOURCE_NAME = "index.mustache.html"; | ||
private const string CSS_RESOURCE_NAME = "main.css"; | ||
private const string JAVASCRIPT_RESOURCE_NAME = "main.js"; | ||
private readonly Assembly _assembly; | ||
private readonly string _resourceNamespace; | ||
|
||
public DefaultResourceProvider() | ||
{ | ||
_assembly = typeof(MessagesToHtmlWriter).Assembly; | ||
_resourceNamespace = "Cucumber.HtmlFormatter.Resources."; | ||
} | ||
|
||
/// <summary> | ||
/// Constructor with custom assembly and namespace | ||
/// </summary> | ||
/// <param name="assembly">The assembly to load resources from</param> | ||
/// <param name="resourceNamespace">The namespace prefix for resources</param> | ||
public DefaultResourceProvider(Assembly assembly, string resourceNamespace) | ||
{ | ||
_assembly = assembly; | ||
_resourceNamespace = resourceNamespace; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public string GetTemplateResource() | ||
{ | ||
return GetResource(TEMPLATE_RESOURCE_NAME); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public string GetCssResource() | ||
{ | ||
return GetResource(CSS_RESOURCE_NAME); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public string GetJavaScriptResource() | ||
{ | ||
return GetResource(JAVASCRIPT_RESOURCE_NAME); | ||
} | ||
|
||
/// <summary> | ||
/// Gets a resource from the assembly | ||
/// </summary> | ||
/// <param name="name">The resource name</param> | ||
/// <returns>The resource content</returns> | ||
protected string GetResource(string name) | ||
{ | ||
var resourceStream = _assembly.GetManifestResourceStream(_resourceNamespace + name); | ||
if (resourceStream == null) | ||
throw new InvalidOperationException($"Resource '{name}' not found in assembly '{_assembly.FullName}'"); | ||
|
||
using var reader = new StreamReader(resourceStream); | ||
return reader.ReadToEnd(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using System.IO; | ||
|
||
namespace Cucumber.HtmlFormatter; | ||
|
||
/// <summary> | ||
/// Interface for providing resources to the HTML formatter | ||
/// </summary> | ||
public interface IResourceProvider | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we indicate that his is an experimental API? If we're planning to do a settings object, with builder I imagine use of that object would be something like,
And with sensible defaults in place if a particular method of the builder isn't called. The IResourceProvider doesn't support those sensible defaults and so I imagine it will be phased out again too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Highlighted that this is experimental |
||
{ | ||
/// <summary> | ||
/// Gets the HTML template | ||
/// </summary> | ||
/// <returns>The HTML template</returns> | ||
string GetTemplateResource(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if the template is suitable for replacement. It is not actually a mustache template, it just looks like one. There is a hard coded assumption in the code that the template contains But that is acceptable if this is marked as an experimental API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently I need this for the tweaking, but the interface is marked as experimental. But you are right, in long term, we should not need this. |
||
|
||
/// <summary> | ||
/// Gets the CSS resource | ||
/// </summary> | ||
/// <returns>The CSS resource</returns> | ||
string GetCssResource(); | ||
|
||
/// <summary> | ||
/// Gets the JavaScript resource | ||
/// </summary> | ||
/// <returns>The JavaScript resource</returns> | ||
string GetJavaScriptResource(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using Cucumber.HtmlFormatter; | ||
|
||
namespace Cucumber.HtmlFormatterTest; | ||
|
||
[TestClass] | ||
public class DefaultResourceProviderTest | ||
{ | ||
private DefaultResourceProvider _resourceProvider = null!; | ||
|
||
[TestInitialize] | ||
public void Setup() | ||
{ | ||
_resourceProvider = new DefaultResourceProvider(); | ||
} | ||
|
||
[TestMethod] | ||
public void GetTemplateResource_ReturnsNonEmptyString() | ||
{ | ||
// Act | ||
var template = _resourceProvider.GetTemplateResource(); | ||
|
||
// Assert | ||
Assert.IsNotNull(template, "Template resource should not be null"); | ||
Assert.IsTrue(!string.IsNullOrWhiteSpace(template), "Template resource should not be empty"); | ||
Assert.IsTrue(template.Contains("{{css}}"), "Template should contain CSS placeholder"); | ||
Assert.IsTrue(template.Contains("{{messages}}"), "Template should contain messages placeholder"); | ||
Assert.IsTrue(template.Contains("{{script}}"), "Template should contain script placeholder"); | ||
} | ||
|
||
[TestMethod] | ||
public void GetCssResource_ReturnsNonEmptyString() | ||
{ | ||
// Act | ||
var css = _resourceProvider.GetCssResource(); | ||
|
||
// Assert | ||
Assert.IsNotNull(css, "CSS resource should not be null"); | ||
Assert.IsTrue(!string.IsNullOrWhiteSpace(css), "CSS resource should not be empty"); | ||
} | ||
|
||
[TestMethod] | ||
public void GetJavaScriptResource_ReturnsNonEmptyString() | ||
{ | ||
// Act | ||
var javascript = _resourceProvider.GetJavaScriptResource(); | ||
|
||
// Assert | ||
Assert.IsNotNull(javascript, "JavaScript resource should not be null"); | ||
Assert.IsTrue(!string.IsNullOrWhiteSpace(javascript), "JavaScript resource should not be empty"); | ||
} | ||
|
||
[TestMethod] | ||
public void AllResources_LoadSuccessfully() | ||
{ | ||
// This test verifies that all resources can be loaded in sequence without errors | ||
|
||
// Act & Assert - if any of these throw an exception, the test will fail | ||
var template = _resourceProvider.GetTemplateResource(); | ||
Assert.IsNotNull(template, "Template resource should not be null"); | ||
|
||
var css = _resourceProvider.GetCssResource(); | ||
Assert.IsNotNull(css, "CSS resource should not be null"); | ||
|
||
var javascript = _resourceProvider.GetJavaScriptResource(); | ||
Assert.IsNotNull(javascript, "JavaScript resource should not be null"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be private now I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done