Skip to content

Commit 6d0bc01

Browse files
authored
Merge pull request #3649 from tommy9/next
TODO marker matching enhancements
2 parents 534cd22 + 7c1d1f4 commit 6d0bc01

File tree

5 files changed

+103
-33
lines changed

5 files changed

+103
-33
lines changed

RetailCoder.VBE/UI/RubberduckUI.Designer.cs

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

RetailCoder.VBE/UI/RubberduckUI.resx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,13 @@ Warning: All customized settings will be lost. Your old file will be saved in '
382382
<value>Version {0}</value>
383383
</data>
384384
<data name="TodoMarkerBug" xml:space="preserve">
385-
<value>BUG </value>
385+
<value>BUG</value>
386386
</data>
387387
<data name="TodoMarkerNote" xml:space="preserve">
388-
<value>NOTE </value>
388+
<value>NOTE</value>
389389
</data>
390390
<data name="TodoMarkerTodo" xml:space="preserve">
391-
<value>TODO </value>
391+
<value>TODO</value>
392392
</data>
393393
<data name="AllImplementations_Caption" xml:space="preserve">
394394
<value>Implementations of '{0}'</value>

RetailCoder.VBE/UI/ToDoItems/ToDoExplorerViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Globalization;
55
using System.Linq;
66
using System.Windows;
7+
using System.Text.RegularExpressions;
78
using NLog;
89
using Rubberduck.Parsing.VBA;
910
using Rubberduck.Settings;
@@ -245,7 +246,7 @@ private IEnumerable<ToDoItem> GetToDoMarkers(CommentNode comment)
245246
{
246247
var markers = _configService.LoadConfiguration().UserSettings.ToDoListSettings.ToDoMarkers;
247248
return markers.Where(marker => !string.IsNullOrEmpty(marker.Text)
248-
&& comment.CommentText.ToLowerInvariant().Contains(marker.Text.ToLowerInvariant()))
249+
&& Regex.IsMatch(comment.CommentText, @"\b" + Regex.Escape(marker.Text) + @"\b", RegexOptions.IgnoreCase))
249250
.Select(marker => new ToDoItem(marker.Text, comment));
250251
}
251252

Retailcoder.VBE/UI/RubberduckUI.resx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,13 @@ Warning: All customized settings will be lost. Your old file will be saved in '
382382
<value>Version {0}</value>
383383
</data>
384384
<data name="TodoMarkerBug" xml:space="preserve">
385-
<value>BUG </value>
385+
<value>BUG</value>
386386
</data>
387387
<data name="TodoMarkerNote" xml:space="preserve">
388-
<value>NOTE </value>
388+
<value>NOTE</value>
389389
</data>
390390
<data name="TodoMarkerTodo" xml:space="preserve">
391-
<value>TODO </value>
391+
<value>TODO</value>
392392
</data>
393393
<data name="AllImplementations_Caption" xml:space="preserve">
394394
<value>Implementations of '{0}'</value>

RubberduckTests/TodoExplorer/TodoExplorerTests.cs

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,23 @@ public class TodoExplorerTests
1818
[TestCategory("Annotations")]
1919
public void PicksUpComments()
2020
{
21-
var content =
21+
const string inputCode =
2222
@"' Todo this is a todo comment
2323
' Note this is a note comment
2424
' Bug this is a bug comment
2525
";
2626

2727
var builder = new MockVbeBuilder();
2828
var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected)
29-
.AddComponent("Module1", ComponentType.StandardModule, content);
29+
.AddComponent("Module1", ComponentType.StandardModule, inputCode)
30+
.Build();
3031

31-
var vbe = builder.AddProject(project.Build()).Build();
32+
var vbe = builder.AddProject(project).Build();
3233
var parser = MockParser.Create(vbe.Object);
3334
using (var state = parser.State)
3435
{
35-
var vm = new ToDoExplorerViewModel(state, GetConfigService(), GetOperatingSystemMock().Object);
36+
var cs = GetConfigService(new[] { "TODO", "NOTE", "BUG" });
37+
var vm = new ToDoExplorerViewModel(state, cs, GetOperatingSystemMock().Object);
3638

3739
parser.Parse(new CancellationTokenSource());
3840
if (state.Status >= ParserState.Error)
@@ -42,15 +44,15 @@ public void PicksUpComments()
4244

4345
var comments = vm.Items.Select(s => s.Type);
4446

45-
Assert.IsTrue(comments.SequenceEqual(new[] { "TODO ", "NOTE ", "BUG " }));
47+
Assert.IsTrue(comments.SequenceEqual(new[] { "TODO", "NOTE", "BUG" }));
4648
}
4749
}
4850

4951
[TestMethod]
5052
[TestCategory("Annotations")]
5153
public void PicksUpComments_StrangeCasing()
5254
{
53-
var content =
55+
const string inputCode =
5456
@"' tODO this is a todo comment
5557
' NOTE this is a note comment
5658
' bug this is a bug comment
@@ -59,13 +61,84 @@ public void PicksUpComments_StrangeCasing()
5961

6062
var builder = new MockVbeBuilder();
6163
var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected)
62-
.AddComponent("Module1", ComponentType.StandardModule, content);
64+
.AddComponent("Module1", ComponentType.StandardModule, inputCode)
65+
.Build();
66+
67+
var vbe = builder.AddProject(project).Build();
68+
var parser = MockParser.Create(vbe.Object);
69+
using (var state = parser.State)
70+
{
71+
var cs = GetConfigService(new[] { "TODO", "NOTE", "BUG" });
72+
var vm = new ToDoExplorerViewModel(state, cs, GetOperatingSystemMock().Object);
73+
74+
parser.Parse(new CancellationTokenSource());
75+
if (state.Status >= ParserState.Error)
76+
{
77+
Assert.Inconclusive("Parser Error");
78+
}
79+
80+
var comments = vm.Items.Select(s => s.Type);
81+
82+
Assert.IsTrue(comments.SequenceEqual(new[] { "TODO", "NOTE", "BUG", "BUG" }));
83+
}
84+
}
85+
86+
[TestMethod]
87+
[TestCategory("Annotations")]
88+
public void PicksUpComments_SpecialCharacters()
89+
{
90+
const string inputCode =
91+
@"' To-do - this is a todo comment
92+
' N@TE this is a note comment
93+
' bug this should work with a trailing space
94+
' bug: this should not be seen due to the colon
95+
";
96+
97+
var builder = new MockVbeBuilder();
98+
var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected)
99+
.AddComponent("Module1", ComponentType.StandardModule, inputCode)
100+
.Build();
101+
102+
var vbe = builder.AddProject(project).Build();
103+
var parser = MockParser.Create(vbe.Object);
104+
using (var state = parser.State)
105+
{
106+
var cs = GetConfigService(new[] { "TO-DO", "N@TE", "BUG " });
107+
var vm = new ToDoExplorerViewModel(state, cs, GetOperatingSystemMock().Object);
108+
109+
parser.Parse(new CancellationTokenSource());
110+
if (state.Status >= ParserState.Error)
111+
{
112+
Assert.Inconclusive("Parser Error");
113+
}
114+
115+
var comments = vm.Items.Select(s => s.Type);
116+
117+
Assert.IsTrue(comments.SequenceEqual(new[] { "TO-DO", "N@TE", "BUG " }));
118+
}
119+
}
120+
121+
[TestMethod]
122+
[TestCategory("Annotations")]
123+
public void AvoidsFalsePositiveComments()
124+
{
125+
const string inputCode =
126+
@"' Todon't should not get picked up
127+
' Debug.print() would trigger false positive if word boundaries not used
128+
' Denoted
129+
";
130+
131+
var builder = new MockVbeBuilder();
132+
var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected)
133+
.AddComponent("Module1", ComponentType.StandardModule, inputCode)
134+
.Build();
63135

64-
var vbe = builder.AddProject(project.Build()).Build();
136+
var vbe = builder.AddProject(project).Build();
65137
var parser = MockParser.Create(vbe.Object);
66138
using (var state = parser.State)
67139
{
68-
var vm = new ToDoExplorerViewModel(state, GetConfigService(), GetOperatingSystemMock().Object);
140+
var cs = GetConfigService(new[] { "TODO", "NOTE", "BUG" });
141+
var vm = new ToDoExplorerViewModel(state, cs, GetOperatingSystemMock().Object);
69142

70143
parser.Parse(new CancellationTokenSource());
71144
if (state.Status >= ParserState.Error)
@@ -75,30 +148,31 @@ public void PicksUpComments_StrangeCasing()
75148

76149
var comments = vm.Items.Select(s => s.Type);
77150

78-
Assert.IsTrue(comments.SequenceEqual(new[] { "TODO ", "NOTE ", "BUG ", "BUG " }));
151+
Assert.IsTrue(comments.Count() == 0);
79152
}
80153
}
81154

82155
[TestMethod]
83156
[TestCategory("Annotations")]
84157
public void RemoveRemovesComment()
85158
{
86-
var input =
159+
const string inputCode =
87160
@"Dim d As Variant ' bug should be Integer";
88161

89-
var expected =
162+
const string expected =
90163
@"Dim d As Variant ";
91164

92165
var builder = new MockVbeBuilder();
93166
var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected)
94-
.AddComponent("Module1", ComponentType.StandardModule, input)
167+
.AddComponent("Module1", ComponentType.StandardModule, inputCode)
95168
.Build();
96169

97170
var vbe = builder.AddProject(project).Build();
98171
var parser = MockParser.Create(vbe.Object);
99172
using (var state = parser.State)
100173
{
101-
var vm = new ToDoExplorerViewModel(state, GetConfigService(), GetOperatingSystemMock().Object);
174+
var cs = GetConfigService(new[] { "TODO", "NOTE", "BUG" });
175+
var vm = new ToDoExplorerViewModel(state, cs, GetOperatingSystemMock().Object);
102176

103177
parser.Parse(new CancellationTokenSource());
104178
if (state.Status >= ParserState.Error)
@@ -115,24 +189,19 @@ public void RemoveRemovesComment()
115189
}
116190
}
117191

118-
private IGeneralConfigService GetConfigService()
192+
private IGeneralConfigService GetConfigService(string[] markers)
119193
{
120194
var configService = new Mock<IGeneralConfigService>();
121-
configService.Setup(c => c.LoadConfiguration()).Returns(GetTodoConfig);
195+
configService.Setup(c => c.LoadConfiguration()).Returns(GetTodoConfig(markers));
122196

123197
return configService.Object;
124198
}
125199

126-
private Configuration GetTodoConfig()
200+
private Configuration GetTodoConfig(string[] markers)
127201
{
128202
var todoSettings = new ToDoListSettings
129203
{
130-
ToDoMarkers = new[]
131-
{
132-
new ToDoMarker("NOTE "),
133-
new ToDoMarker("TODO "),
134-
new ToDoMarker("BUG ")
135-
}
204+
ToDoMarkers = markers.Select(m => new ToDoMarker(m)).ToArray()
136205
};
137206

138207
var userSettings = new UserSettings(null, null, todoSettings, null, null, null, null);

0 commit comments

Comments
 (0)