Skip to content

Commit 8b4fdcf

Browse files
authored
PR #80 from warriordog/feat/full-text-in-reports
feat: new render pipeline
2 parents db17ecd + a0ba55d commit 8b4fdcf

28 files changed

+888
-284
lines changed

ModShark.Tests/Reports/Document/DocumentBuilderTests.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void ToString_ShouldRenderMarkdownDocument()
1313
RenderDocument(builder);
1414
var document = builder.ToString();
1515

16-
document.Should().Be("# Title1\n# Title2\n\nSection1\n\n## Header1\n## Header2\n**Bold1** **Bold2** *Italics1* *Italics2* `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n* Item1\n* Item2\n * Item3\n||Spoiler1||||Spoiler2||\n");
16+
document.Should().Be("# Title1\n# Title2\n\nSection1\n\n## Header1\n## Header2\n**Bold1** **Bold2** *Italics1* *Italics2* `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n* Item1\n* Item2\n * Item3\n||Spoiler1||||Spoiler2||new line\n");
1717
}
1818

1919
[Test]
@@ -24,7 +24,7 @@ public void ToString_ShouldRenderMFMDocument()
2424
RenderDocument(builder);
2525
var document = builder.ToString();
2626

27-
document.Should().Be("<b>Title1</b>\n<b>Title2</b>\n\nSection1\n\n<b>Header1</b>\n<b>Header2</b>\n<b>Bold1</b> <b>Bold2</b> <i>Italics1</i> <i>Italics2</i> `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n- Item1\n- Item2\n - Item3\n$[blur Spoiler1]$[blur Spoiler2]\n");
27+
document.Should().Be("<b>Title1</b>\n<b>Title2</b>\n\nSection1\n\n<b>Header1</b>\n<b>Header2</b>\n<b>Bold1</b> <b>Bold2</b> <i>Italics1</i> <i>Italics2</i> `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n- Item1\n- Item2\n - Item3\n$[blur Spoiler1]$[blur Spoiler2]new line\n");
2828
}
2929

3030
[Test]
@@ -35,7 +35,7 @@ public void ToString_ShouldRenderHTMLDocument()
3535
RenderDocument(builder);
3636
var document = builder.ToString();
3737

38-
document.Should().Be("<h1>Title1</h1><h1>Title2</h1><div>Section1</div><div><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li><li><ul><li>Item3</li></ul></li></ul>Spoiler1Spoiler2</div>");
38+
document.Should().Be("<h1>Title1</h1><h1>Title2</h1><div>Section1</div><div><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li><li><ul><li>Item3</li></ul></li></ul>Spoiler1Spoiler2new\nline</div>");
3939
}
4040

4141
[Test]
@@ -46,7 +46,7 @@ public void ToString_ShouldRenderHTML5Document()
4646
RenderDocument(builder);
4747
var document = builder.ToString();
4848

49-
document.Should().Be("<h1>Title1</h1><h1>Title2</h1><section>Section1</section><section><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li><li><ul><li>Item3</li></ul></li></ul><details style=\"display: inline\"><summary>spoiler</summary>Spoiler1</details><details style=\"display: inline\"><summary>hidden</summary>Spoiler2</details></section>");
49+
document.Should().Be("<h1>Title1</h1><h1>Title2</h1><section>Section1</section><section><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li><li><ul><li>Item3</li></ul></li></ul><details style=\"display: inline\"><summary>spoiler</summary>Spoiler1</details><details style=\"display: inline\"><summary>hidden</summary>Spoiler2</details>new\nline</section>");
5050
}
5151

5252
[TestCase(0)]
@@ -140,6 +140,7 @@ private void RenderDocument(DocumentBuilder builder)
140140
.BeginSpoiler("hidden")
141141
.AppendText("Spoiler2")
142142
.End()
143+
.AppendInline("new\nline")
143144
.End();
144145
}
145146
}

ModShark.Tests/Reports/Document/Format/HTMLFormatTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,22 @@ public void Text_ShouldEscapeHTML(string input, string expected)
3939

4040
actual.Should().Be(expected);
4141
}
42+
43+
[TestCase("", "")]
44+
[TestCase("hello, world", "hello, world")]
45+
[TestCase("<", "&lt;")]
46+
[TestCase(">", "&gt;")]
47+
[TestCase("&", "&amp;")]
48+
[TestCase("\"", "&quot;")]
49+
[TestCase("'", "&#39;")]
50+
[TestCase("<span class=\"foo\">'&amp;'</span>", "&lt;span class=&quot;foo&quot;&gt;&#39;&amp;amp;&#39;&lt;/span&gt;")]
51+
[TestCase(">", "&gt;")]
52+
public void TextInline_ShouldEscapeHTML(string input, string expected)
53+
{
54+
var format = new HTMLFormat();
55+
56+
var actual = format.TextInline(input);
57+
58+
actual.Should().Be(expected);
59+
}
4260
}

ModShark.Tests/Reports/Document/Format/MarkdownFormatTests.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,67 @@ public void Text_ShouldEscapeMarkdown(string input, string expected)
3838

3939
actual.Should().Be(expected);
4040
}
41+
42+
[TestCase("", "")]
43+
[TestCase("Hello, world", "Hello, world")]
44+
[TestCase("-text", "-text")]
45+
[TestCase("*text", "*text")]
46+
[TestCase(" - text", @" \- text")]
47+
[TestCase(" * text", @" \* text")]
48+
[TestCase("- text", @"\- text")]
49+
[TestCase("* text", @"\* text")]
50+
[TestCase("|", @"\|")]
51+
[TestCase("#", @"\#")]
52+
[TestCase(@"\", @"\\")]
53+
[TestCase(" |", @" \|")]
54+
[TestCase(" #", @" \#")]
55+
[TestCase(@" \", @" \\")]
56+
[TestCase("text |", "text |")]
57+
[TestCase("text #", "text #")]
58+
[TestCase(@"text \", @"text \\")]
59+
[TestCase("<tag>", @"\<tag>")]
60+
[TestCase("<tag/>", @"\<tag/>")]
61+
[TestCase("</tag>", @"\</tag>")]
62+
[TestCase("<tag >", "<tag >")]
63+
[TestCase("< tag>", "< tag>")]
64+
[TestCase("< tag >", "< tag >")]
65+
[TestCase("[not a link](https://example.com)", @"[not a link\](https://example.com)")]
66+
[TestCase("[not a link]", "[not a link]")]
67+
public void TextInline_ShouldEscapeMarkdown(string input, string expected)
68+
{
69+
var format = new MarkdownFormat();
70+
71+
var actual = format.TextInline(input);
72+
73+
actual.Should().Be(expected);
74+
}
75+
76+
[TestCase("", "")]
77+
[TestCase(" ", " ")]
78+
[TestCase("\t", " ")]
79+
[TestCase("\r", " ")]
80+
[TestCase("\n", " ")]
81+
[TestCase("\v", " ")]
82+
public void Text_ShouldEscapeWhitespace(string input, string expected)
83+
{
84+
var format = new MarkdownFormat();
85+
86+
var actual = format.TextInline(input);
87+
88+
actual.Should().Be(expected);
89+
}
90+
91+
[TestCase(" ", " ")]
92+
[TestCase("\t \t", " ")]
93+
[TestCase("\r \r", " ")]
94+
[TestCase("\n \n", " ")]
95+
[TestCase("\v \v", " ")]
96+
public void Text_ShouldEscapeConsecutiveWhitespace(string input, string expected)
97+
{
98+
var format = new MarkdownFormat();
99+
100+
var actual = format.TextInline(input);
101+
102+
actual.Should().Be(expected);
103+
}
41104
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using FluentAssertions;
2+
using ModShark.Reports.Document;
3+
using ModShark.Reports.Render;
4+
5+
namespace ModShark.Tests.Reports.Render;
6+
7+
public class RenderExtensionsTests
8+
{
9+
[Test]
10+
public void AppendFullFlaggedText_ShouldRenderMixed()
11+
{
12+
var ranges = new List<Range> { new(0, 5), new(11, 13) };
13+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
14+
15+
builder.AppendFullFlaggedText("hello, world!", ranges);
16+
17+
var result = builder.ToString();
18+
result.Should().Be("||**`hello`**`, worl`**`d!`**||");
19+
}
20+
21+
[Test]
22+
public void AppendFullFlaggedText_ShouldRenderAllText()
23+
{
24+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
25+
26+
builder.AppendFullFlaggedText("hello, world!", new List<Range>());
27+
28+
var result = builder.ToString();
29+
result.Should().Be("||`hello, world!`||");
30+
}
31+
32+
[Test]
33+
public void AppendFullFlaggedText_ShouldRenderAllFlagged()
34+
{
35+
var ranges = new List<Range> { Range.All };
36+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
37+
38+
builder.AppendFullFlaggedText("hello, world!", ranges);
39+
40+
var result = builder.ToString();
41+
result.Should().Be("||**`hello, world!`**||");
42+
}
43+
44+
[Test]
45+
public void AppendFullFlaggedText_ShouldIgnoreOutOfRange()
46+
{
47+
var ranges = new List<Range> { new(20, 25), Range.StartAt(23) };
48+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
49+
50+
builder.AppendFullFlaggedText("hello, world!", ranges);
51+
52+
var result = builder.ToString();
53+
result.Should().Be("||`hello, world!`||");
54+
}
55+
56+
[Test]
57+
public void AppendFullFlaggedText_ShouldDoNothing_ForEmptyInput()
58+
{
59+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
60+
61+
builder.AppendFullFlaggedText("", new List<Range>());
62+
63+
var result = builder.ToString();
64+
result.Should().Be("");
65+
}
66+
67+
[Test]
68+
public void AppendMinimalFlaggedText_ShouldIncludeAllSegments()
69+
{
70+
var ranges = new List<Range> { new(0, 5), new(11, 13) };
71+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
72+
73+
builder.AppendMinimalFlaggedText("hello, world!", ranges);
74+
75+
var result = builder.ToString();
76+
result.Should().Be("||`hello`||, ||`d!`||");
77+
}
78+
79+
[Test]
80+
public void AppendMinimalFlaggedText_ShouldCapBounds()
81+
{
82+
var ranges = new List<Range> { new(0, 5), new(11, 25) };
83+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
84+
85+
builder.AppendMinimalFlaggedText("hello, world!", ranges);
86+
87+
var result = builder.ToString();
88+
result.Should().Be("||`hello`||, ||`d!`||");
89+
}
90+
91+
[Test]
92+
public void AppendMinimalFlaggedText_ShouldIgnoreOutOfRange()
93+
{
94+
var ranges = new List<Range> { new(0, 5), new(11, 13), new (25, 30) };
95+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
96+
97+
builder.AppendMinimalFlaggedText("hello, world!", ranges);
98+
99+
var result = builder.ToString();
100+
result.Should().Be("||`hello`||, ||`d!`||");
101+
}
102+
103+
[Test]
104+
public void AppendMinimalFlaggedText_ShouldDoNothing_ForEmptyInput()
105+
{
106+
var builder = new DocumentBuilder(DocumentFormat.Markdown);
107+
108+
builder.AppendMinimalFlaggedText("", new List<Range>());
109+
110+
var result = builder.ToString();
111+
result.Should().Be("");
112+
}
113+
}

ModShark.Tests/Reports/Render/RenderServiceTests.cs

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
using ModShark.Reports.Document;
44
using ModShark.Reports.Render;
55
using ModShark.Services;
6+
using ModShark.Utils;
67
using Moq;
78
using SharkeyDB.Entities;
9+
using Range = System.Range;
810

911
namespace ModShark.Tests.Reports.Render;
1012

@@ -88,8 +90,14 @@ public void Setup()
8890
{
8991
Text =
9092
{
91-
["software", "soapbox 1.2.3"] = true,
92-
["description", "free speech community"] = true
93+
["software"] = new MultiMap<string, Range>
94+
{
95+
{ "soapbox 1.2.3", Range.EndAt(7) }
96+
},
97+
["description"] = new MultiMap<string, Range>
98+
{
99+
{ "free speech community", Range.EndAt(12) }
100+
}
93101
}
94102
}
95103
}
@@ -104,7 +112,10 @@ public void Setup()
104112
{
105113
Text =
106114
{
107-
["text", "slur"] = true
115+
["text"] = new MultiMap<string, Range>
116+
{
117+
{ "slur", Range.All }
118+
}
108119
}
109120
}
110121
},
@@ -115,7 +126,10 @@ public void Setup()
115126
{
116127
Text =
117128
{
118-
["bio", "Age: 12"] = true
129+
["bio"] = new MultiMap<string, Range>
130+
{
131+
{ "Age: 12", Range.All }
132+
}
119133
}
120134
}
121135
}
@@ -131,7 +145,10 @@ public void Setup()
131145
{
132146
Text =
133147
{
134-
["text", "kys"] = true
148+
["text"] = new MultiMap<string, Range>
149+
{
150+
{ "kys", Range.All }
151+
}
135152
}
136153
}
137154
},
@@ -143,8 +160,14 @@ public void Setup()
143160
{
144161
Text =
145162
{
146-
["text", "https://forbidden-domain.example.com"] = true,
147-
["emoji", "nsfw_emoji"] = true
163+
["text"] = new MultiMap<string, Range>
164+
{
165+
{ "https://forbidden-domain.example.com", Range.StartAt(8) }
166+
},
167+
["emoji"] = new MultiMap<string, Range>
168+
{
169+
{ "nsfw_emoji", Range.All }
170+
}
148171
}
149172
}
150173
}
@@ -202,18 +225,56 @@ public void RenderReport_ShouldRenderNoteReports()
202225
}
203226

204227
[Test]
205-
public void RenderReport_ShouldIncludeFlaggedText()
228+
public void RenderReport_ShouldNotIncludeAnyContent_WhenFlagInclusionIsNone()
206229
{
207230
var document = ServiceUnderTest
208-
.RenderReport(FakeReport, DocumentFormat.HTML)
231+
.RenderReport(FakeReport, DocumentFormat.HTML, includeFlags: FlagInclusion.None)
232+
.ToString();
233+
234+
document.Should()
235+
.NotContain("soapbox")
236+
.And.NotContain("1.2.3")
237+
.And.NotContain("free speech")
238+
.And.NotContain("community")
239+
.And.NotContain("slur")
240+
.And.NotContain("Age: 12")
241+
.And.NotContain("kys")
242+
.And.NotContain("forbidden-domain.example.com");
243+
}
244+
245+
[Test]
246+
public void RenderReport_ShouldIncludeFlaggedContent_WhenFlagInclusionIsMinimal()
247+
{
248+
var document = ServiceUnderTest
249+
.RenderReport(FakeReport, DocumentFormat.HTML, includeFlags: FlagInclusion.Minimal)
250+
.ToString();
251+
252+
document.Should()
253+
.Contain("soapbox")
254+
.And.NotContain("1.2.3")
255+
.And.Contain("free speech")
256+
.And.NotContain("community")
257+
.And.Contain("slur")
258+
.And.Contain("Age: 12")
259+
.And.Contain("kys")
260+
.And.Contain("forbidden-domain.example.com");
261+
}
262+
263+
[Test]
264+
public void RenderReport_ShouldIncludeAllContent_WhenFlagInclusionIsFull()
265+
{
266+
var document = ServiceUnderTest
267+
.RenderReport(FakeReport, DocumentFormat.HTML, includeFlags: FlagInclusion.Full)
209268
.ToString();
210269

211270
document.Should()
212-
.Contain("soapbox 1.2.3")
213-
.And.Contain("free speech community")
271+
.Contain("soapbox")
272+
.And.Contain("1.2.3")
273+
.And.Contain("free speech")
274+
.And.Contain("community")
214275
.And.Contain("slur")
215276
.And.Contain("Age: 12")
216277
.And.Contain("kys")
217-
.And.Contain("https://forbidden-domain.example.com");
278+
.And.Contain("forbidden-domain.example.com");
218279
}
219280
}

0 commit comments

Comments
 (0)