Skip to content

Commit be81865

Browse files
authored
Major add of unit tests for most commands. Some fixes as a resulting benefit of these new tests to improve the core functionality and handle outlier behavior. (#189)
1 parent 534a000 commit be81865

26 files changed

+2464
-235
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,4 @@ __pycache__/
269269
/AppInspector/linux/ApplicationInspector
270270
/Microsoft.DevSkim/linux/ApplicationInspector
271271
/AppInspector/Resources/defaultRules.json
272+
/UnitTest.Commands/output

AppInspector/Commands/AllCommandOptions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ public class TagDiffCommandOptions : AllCommandOptions
7676
[Option('t', "test-type", Required = false, HelpText = "Type of test to run [equality|inequality]", Default = "equality")]
7777
public string TestType { get; set; }
7878

79+
[Option('k', "file-path-exclusions", Required = false, HelpText = "Exclude source files (none|default: sample,example,test,docs,.vs,.git)", Default = "sample,example,test,docs,.vs,.git")]
80+
public string FilePathExclusions { get; set; }
81+
7982
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
8083
public string CustomRulesPath { get; set; }
8184

@@ -103,6 +106,9 @@ public class TagTestCommandOptions : AllCommandOptions
103106
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
104107
public string CustomRulesPath { get; set; }
105108

109+
[Option('k', "file-path-exclusions", Required = false, HelpText = "Exclude source files (none|default: sample,example,test,docs,.vs,.git)", Default = "sample,example,test,docs,.vs,.git")]
110+
public string FilePathExclusions { get; set; }
111+
106112
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
107113
public string OutputFilePath { get; set; }
108114

AppInspector/Commands/AnalyzeCommand.cs

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -159,22 +159,32 @@ void ConfigFileOutput()
159159
{
160160
WriteOnce.SafeLog("AnalyzeCommand::ConfigOutput", LogLevel.Trace);
161161

162-
//Set output type, format and outstream
163-
_outputWriter = WriterFactory.GetWriter(_arg_fileFormat ?? "text", (string.IsNullOrEmpty(_arg_outputFile)) ? null : "text", _arg_outputTextFormat);
162+
WriteOnce.FlushAll();//in case called more than once
163+
164+
//error check for no output
165+
if (string.IsNullOrEmpty(_arg_outputFile) && _arg_consoleVerbosityLevel.ToLower() == "none")
166+
{
167+
throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_NO_OUTPUT));
168+
}
169+
164170
if (_arg_fileFormat == "html")
165171
{
166-
if (!string.IsNullOrEmpty(_arg_outputFile))
167-
WriteOnce.Info("output file ignored for html format");
168-
_outputWriter.TextWriter = Console.Out;
172+
if (!string.IsNullOrEmpty(_arg_outputFile)) //dependent local files won't be there; TODO look into dir copy to target!
173+
{
174+
_arg_outputFile = String.Empty;
175+
WriteOnce.Info("output file argument ignored for html format");
176+
}
169177

170178
if (!_arg_outputUniqueTagsOnly) //fix #183
171179
throw new Exception(ErrMsg.GetString(ErrMsg.ID.ANALYZE_NODUPLICATES_HTML_FORMAT));
172180

173181
if (_arg_simpleTagsOnly) //won't work for html that expects full data
174-
throw new Exception(ErrMsg.GetString(ErrMsg.ID.ANALYZE_NODUPLICATES_HTML_FORMAT));
175-
182+
throw new Exception(ErrMsg.GetString(ErrMsg.ID.ANALYZE_SIMPLETAGS_HTML_FORMAT));
176183
}
177-
else if (!string.IsNullOrEmpty(_arg_outputFile))
184+
185+
//Set outstream
186+
_outputWriter = WriterFactory.GetWriter(_arg_fileFormat ?? "text", (string.IsNullOrEmpty(_arg_outputFile)) ? null : "text", _arg_outputTextFormat);
187+
if (!string.IsNullOrEmpty(_arg_outputFile))
178188
{
179189
_outputWriter.TextWriter = File.CreateText(_arg_outputFile);//not needed if html output since application controlled
180190
}
@@ -377,8 +387,6 @@ public override int Run()
377387
else
378388
{
379389
WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "analyze"));
380-
if (!_arg_suppressBrowserOpen)
381-
WriteOnce.Any(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, "output.html"), true, ConsoleColor.Gray, WriteOnce.ConsoleVerbosity.Low);
382390
}
383391
}
384392
catch (Exception e)
@@ -496,6 +504,8 @@ void ProcessInMemory(string filePath, string fileText, LanguageInfo languageInfo
496504
continue;
497505
else if (addAsFeatureMatch)
498506
_appProfile.MatchList.Add(record);
507+
else
508+
_appProfile.MetaData.TotalMatchesCount -= 1;//reduce e.g. tag counters only as per preferences file
499509
}
500510
}
501511
else
@@ -647,21 +657,28 @@ public void FlushAll()
647657
{
648658
_outputWriter.WriteApp(_appProfile);
649659

650-
if (_outputWriter.TextWriter != null && _arg_fileFormat != "html")
660+
if (_outputWriter.TextWriter != null)
651661
{
652-
_outputWriter.FlushAndClose();//not required for html formal i.e. multiple files already closed
653-
_outputWriter = null;
654-
WriteOnce.Writer = null;
662+
if (_arg_fileFormat != "html")
663+
{
664+
_outputWriter.FlushAndClose();//not required for htmt formal i.e. already closed
665+
_outputWriter = null;
666+
WriteOnce.Writer = null;
655667

656-
//Special case to avoid writing tmp file path to output file for TagTest,TagDiff or when called as a DLL since unnecessary
657-
if (_arg_consoleVerbosityLevel.ToLower() != "none")
668+
//Special case to avoid writing tmp file path to output file for TagTest,TagDiff or when called as a DLL since unnecessary
669+
if (_arg_consoleVerbosityLevel.ToLower() != "none")
670+
{
671+
if (!String.IsNullOrEmpty(_arg_outputFile) && Utils.CLIExecutionContext)
672+
WriteOnce.Info(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, WriteOnce.ConsoleVerbosity.Medium, false);
673+
else
674+
WriteOnce.NewLine();
675+
}
676+
}
677+
else
658678
{
659-
if (!String.IsNullOrEmpty(_arg_outputFile) && Utils.CLIExecutionContext)
660-
WriteOnce.Info(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, WriteOnce.ConsoleVerbosity.Medium, false);
661-
else
662-
WriteOnce.NewLine();
679+
if (!_arg_suppressBrowserOpen && Utils.CLIExecutionContext)
680+
WriteOnce.Any(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, "output.html"), true, ConsoleColor.Gray, WriteOnce.ConsoleVerbosity.Low);
663681
}
664-
665682
}
666683
}
667684
}

AppInspector/Commands/ExportTagsCommand.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,20 @@ private void ConfigFileOutput()
8989
{
9090
WriteOnce.SafeLog("ExportTagsCommand::ConfigOutput", LogLevel.Trace);
9191

92-
//setup output
93-
TextWriter outputWriter;
92+
WriteOnce.FlushAll();//in case called more than once
9493

95-
if (!string.IsNullOrEmpty(_arg_outputFile))
94+
if (string.IsNullOrEmpty(_arg_outputFile) && _arg_consoleVerbosityLevel.ToLower() == "none")
9695
{
97-
outputWriter = File.CreateText(_arg_outputFile);
98-
outputWriter.WriteLine(Utils.GetVersionString());
99-
WriteOnce.Writer = outputWriter;
96+
throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_NO_OUTPUT));
97+
}
98+
else if (!string.IsNullOrEmpty(_arg_outputFile))
99+
{
100+
WriteOnce.Writer = File.CreateText(_arg_outputFile);
101+
WriteOnce.Writer.WriteLine(Utils.GetVersionString());
102+
}
103+
else
104+
{
105+
WriteOnce.Writer = Console.Out;
100106
}
101107
}
102108

AppInspector/Commands/TagDiffCommand.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum TagTestType { Equality, Inequality }
3939
string _arg_test_type_raw;
4040
TagTestType _arg_tagTestType;
4141
string _arg_consoleVerbosityLevel;
42+
string _arg_fileExclusionList;//see exclusion list
4243

4344
public TagDiffCommand(TagDiffCommandOptions opt)
4445
{
@@ -52,6 +53,7 @@ public TagDiffCommand(TagDiffCommandOptions opt)
5253
_arg_logger = opt.Log;
5354
_arg_log_file_path = opt.LogFilePath;
5455
_arg_close_log_on_exit = Utils.CLIExecutionContext ? true : opt.CloseLogOnCommandExit;
56+
_arg_fileExclusionList = opt.FilePathExclusions;
5557

5658
_arg_logger ??= Utils.SetupLogging(opt);
5759
WriteOnce.Log ??= _arg_logger;
@@ -79,6 +81,7 @@ public TagDiffCommand(TagDiffCommandOptions opt)
7981
/// <summary>
8082
/// Establish console verbosity
8183
/// For NuGet DLL use, console is muted overriding any arguments sent
84+
/// Pre: Always call again after ConfigureFileOutput
8285
/// </summary>
8386
void ConfigureConsoleOutput()
8487
{
@@ -115,7 +118,22 @@ void ConfigureCompareType()
115118
void ConfigureFileOutput()
116119
{
117120
WriteOnce.SafeLog("TagDiff::ConfigOutput", LogLevel.Trace);
118-
//intentionally empty as this is put in Run() for this command; see note
121+
122+
WriteOnce.FlushAll();//in case called more than once
123+
124+
if (string.IsNullOrEmpty(_arg_outputFile) && _arg_consoleVerbosityLevel.ToLower() == "none")
125+
{
126+
throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_NO_OUTPUT));
127+
}
128+
else if (!string.IsNullOrEmpty(_arg_outputFile))
129+
{
130+
WriteOnce.Writer = File.CreateText(_arg_outputFile);
131+
WriteOnce.Writer.WriteLine(Utils.GetVersionString());
132+
}
133+
else
134+
{
135+
WriteOnce.Writer = Console.Out;
136+
}
119137
}
120138

121139

@@ -183,6 +201,7 @@ public override int Run()
183201
OutputFileFormat = "json",
184202
CustomRulesPath = _arg_customRulesPath,
185203
IgnoreDefaultRules = _arg_ignoreDefault,
204+
FilePathExclusions = _arg_fileExclusionList,
186205
SimpleTagsOnly = true,
187206
ConsoleVerbosityLevel = "none",
188207
Log = _arg_logger
@@ -194,6 +213,7 @@ public override int Run()
194213
OutputFileFormat = "json",
195214
CustomRulesPath = _arg_customRulesPath,
196215
IgnoreDefaultRules = _arg_ignoreDefault,
216+
FilePathExclusions = _arg_fileExclusionList,
197217
SimpleTagsOnly = true,
198218
ConsoleVerbosityLevel = "none",
199219
Log = _arg_logger
@@ -229,13 +249,8 @@ public override int Run()
229249
else //compare tag results; assumed (result1&2 == AnalyzeCommand.ExitCode.Success)
230250
{
231251
//setup output here rather than top to avoid analyze command output in this command output
232-
TextWriter outputWriter;
233-
if (!string.IsNullOrEmpty(_arg_outputFile))
234-
{
235-
outputWriter = File.CreateText(_arg_outputFile);
236-
outputWriter.WriteLine(Utils.GetVersionString());
237-
WriteOnce.Writer = outputWriter;
238-
}
252+
ConfigureFileOutput();
253+
ConfigureConsoleOutput();//recheck
239254

240255
string file1TagsJson = File.ReadAllText(tmp1);
241256
string file2TagsJson = File.ReadAllText(tmp2);

AppInspector/Commands/TagTestCommand.cs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public class TagTestCommand : Command
2020
{
2121
public enum ExitCode
2222
{
23-
TagsTestSuccess = 0,
24-
SomeTagsFailed = 1,
23+
TestPassed = 0,
24+
TestFailed = 1,
2525
CriticalError = Utils.ExitCode.CriticalError //ensure common value for final exit log mention
2626
}
2727

@@ -34,6 +34,7 @@ enum TagTestType { RulesPresent, RulesNotPresent }
3434
TagTestType _arg_tagTestType;
3535
RuleSet _rulesSet;
3636
string _arg_consoleVerbosityLevel;
37+
string _arg_fileExclusionList;//see exclusion list
3738

3839
/// Compares a set of rules against a source path...
3940
/// Used for both RulesPresent and RulesNotePresent options
@@ -49,6 +50,7 @@ public TagTestCommand(TagTestCommandOptions opt)
4950
_arg_log_file_path = opt.LogFilePath;
5051
_arg_log_level = opt.LogFileLevel;
5152
_arg_close_log_on_exit = Utils.CLIExecutionContext ? true : opt.CloseLogOnCommandExit;
53+
_arg_fileExclusionList = opt.FilePathExclusions;
5254

5355
_arg_logger ??= Utils.SetupLogging(opt);
5456
WriteOnce.Log ??= _arg_logger;
@@ -105,15 +107,20 @@ void ConfigureFileOutput()
105107
{
106108
WriteOnce.SafeLog("TagTestCommand::ConfigOutput", LogLevel.Trace);
107109

108-
WriteOnce.FlushAll();
110+
WriteOnce.FlushAll();//in case called more than once
109111

110-
//setup output
111-
TextWriter outputWriter;
112-
if (!string.IsNullOrEmpty(_arg_outputFile))
112+
if (string.IsNullOrEmpty(_arg_outputFile) && _arg_consoleVerbosityLevel.ToLower() == "none")
113113
{
114-
outputWriter = File.CreateText(_arg_outputFile);
115-
outputWriter.WriteLine(Utils.GetVersionString());
116-
WriteOnce.Writer = outputWriter;
114+
throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_NO_OUTPUT));
115+
}
116+
else if (!string.IsNullOrEmpty(_arg_outputFile))
117+
{
118+
WriteOnce.Writer = File.CreateText(_arg_outputFile);
119+
WriteOnce.Writer.WriteLine(Utils.GetVersionString());
120+
}
121+
else
122+
{
123+
WriteOnce.Writer = Console.Out;
117124
}
118125
}
119126

@@ -211,6 +218,7 @@ public override int Run()
211218
OutputFileFormat = "json",
212219
IgnoreDefaultRules = true,
213220
CustomRulesPath = _arg_customRulesPath,
221+
FilePathExclusions = _arg_fileExclusionList,
214222
SimpleTagsOnly = true,
215223
ConsoleVerbosityLevel = "None",
216224
Log = _arg_logger
@@ -240,15 +248,15 @@ public override int Run()
240248

241249
WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "tagtest"));
242250

243-
exitCode = _arg_tagTestType == TagTestType.RulesPresent ? ExitCode.SomeTagsFailed : ExitCode.TagsTestSuccess;
251+
exitCode = _arg_tagTestType == TagTestType.RulesPresent ? ExitCode.TestFailed : ExitCode.TestPassed;
244252
}
245253
else //assumed (result == AnalyzeCommand.ExitCode.MatchesFound)
246254
{
247255
string file1TagsJson = File.ReadAllText(tmp1);
248256
var file1Tags = JsonConvert.DeserializeObject<TagsFile>(file1TagsJson);
249257
File.Delete(tmp1);
250258

251-
exitCode = ExitCode.TagsTestSuccess;
259+
exitCode = ExitCode.TestPassed;
252260
foreach (Rule r in _rulesSet)
253261
{
254262
//supports both directions by generalizing
@@ -264,22 +272,22 @@ public override int Run()
264272
WriteOnce.Result(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TAGS_FOUND, t), true, WriteOnce.ConsoleVerbosity.High);
265273
else
266274
{
267-
exitCode = ExitCode.SomeTagsFailed;
275+
exitCode = ExitCode.TestFailed;
268276
WriteOnce.Result(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TAGS_MISSING, t), true, WriteOnce.ConsoleVerbosity.High);
269277
}
270278

271-
if (exitCode != ExitCode.TagsTestSuccess)
279+
if (exitCode != ExitCode.TestPassed)
272280
break;
273281
}
274282

275-
if (exitCode != ExitCode.TagsTestSuccess)
283+
if (exitCode != ExitCode.TestPassed)
276284
break;
277285
}
278286

279287
//results
280288
WriteOnce.General(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TEST_TYPE, _arg_tagTestType.ToString()), false, WriteOnce.ConsoleVerbosity.Low);
281289

282-
if (exitCode == ExitCode.SomeTagsFailed)
290+
if (exitCode == ExitCode.TestFailed)
283291
WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.TAGTEST_RESULTS_FAIL), true, ConsoleColor.Red, WriteOnce.ConsoleVerbosity.Low);
284292
else
285293
WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.TAGTEST_RESULTS_SUCCESS), true, ConsoleColor.Green, WriteOnce.ConsoleVerbosity.Low);

AppInspector/Commands/VerifyRulesCommand.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,20 @@ private void ConfigFileOutput()
9090
{
9191
WriteOnce.SafeLog("VerifyRulesCommand::ConfigOutput", LogLevel.Trace);
9292

93-
//setup output
94-
TextWriter outputWriter;
93+
WriteOnce.FlushAll();//in case called more than once
9594

96-
if (!string.IsNullOrEmpty(_arg_outputFile))
95+
if (string.IsNullOrEmpty(_arg_outputFile) && _arg_consoleVerbosityLevel.ToLower() == "none")
9796
{
98-
outputWriter = File.CreateText(_arg_outputFile);
99-
outputWriter.WriteLine(Utils.GetVersionString());
100-
WriteOnce.Writer = outputWriter;
97+
throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_NO_OUTPUT));
98+
}
99+
else if (!string.IsNullOrEmpty(_arg_outputFile))
100+
{
101+
WriteOnce.Writer = File.CreateText(_arg_outputFile);
102+
WriteOnce.Writer.WriteLine(Utils.GetVersionString());
103+
}
104+
else
105+
{
106+
WriteOnce.Writer = Console.Out;
101107
}
102108
}
103109

AppInspector/ErrorMessage.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public enum ID
3131
ANALYZE_REPORTSIZE_WARN,
3232
ANALYZE_NODUPLICATES_HTML_FORMAT,
3333
ANALYZE_SIMPLETAGS_HTML_FORMAT,
34+
CMD_NO_OUTPUT,
3435
CMD_PREPARING_REPORT,
3536
CMD_COMPLETED,
3637
CMD_CRITICAL_FILE_ERR,
@@ -41,7 +42,7 @@ public enum ID
4142
CMD_RUNNING,
4243
CMD_INVALID_RULE_PATH,
4344
CMD_NORULES_SPECIFIED,
44-
CMD_INVALID_LOG_PATH,
45+
CMD_INVALID_REPLACE_LOG_PATH,
4546
TAGDIFF_NO_TAGS_FOUND,
4647
TAGDIFF_RESULTS_DIFFER,
4748
TAGDIFF_RESULTS_GAP,

0 commit comments

Comments
 (0)