Skip to content

Commit

Permalink
Now showing "Results stats" in HTML output. Improved error handling a…
Browse files Browse the repository at this point in the history
…nd message when PBI file is not supplied.
  • Loading branch information
NatVanG committed Jan 21, 2024
1 parent 7d65956 commit fa28eb5
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 47 deletions.
19 changes: 2 additions & 17 deletions PBIXInspectorLibrary/Inspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,7 @@ public Inspector(string pbiFilePath, string rulesFilePath) : base(pbiFilePath, r
AddCustomRulesToRegistry();
}

private PbiFile InitPbiFile(string pbiFilePath)
{
switch (PbiFile.PBIFileType(pbiFilePath))
{
case PbiFile.PBIFileTypeEnum.PBIX:
return new PbixFile(pbiFilePath);
break;
case PbiFile.PBIFileTypeEnum.PBIP:
return new PbipFile(pbiFilePath);
break;
case PbiFile.PBIFileTypeEnum.PBIPReport:
return new PbipReportFile(pbiFilePath);
default:
throw new PBIXInspectorException(string.Format("Could not determine the extension of PBI file with path \"{0}\".", pbiFilePath));
}
}


private void AddCustomRulesToRegistry()
{
Expand Down Expand Up @@ -124,7 +109,7 @@ public IEnumerable<TestResult> Inspect()
{
var testResults = new List<TestResult>();

using (var pbiFile = InitPbiFile(_pbiFilePath))
using (var pbiFile = PbiFileUtils.InitPbiFile(_pbiFilePath))
{
foreach (var entry in this._inspectionRules.PbiEntries)
{
Expand Down
26 changes: 26 additions & 0 deletions PBIXInspectorLibrary/PbiFileUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleToAttribute("PBIXInspectorTests")]

namespace PBIXInspectorLibrary
{
internal class PbiFileUtils
{
internal static PbiFile InitPbiFile(string pbiFilePath)
{
if (string.IsNullOrEmpty(pbiFilePath)) throw new PBIXInspectorException("PBI file path is empty.");

switch (PbiFile.PBIFileType(pbiFilePath))
{
case PbiFile.PBIFileTypeEnum.PBIX:
return new PbixFile(pbiFilePath);
case PbiFile.PBIFileTypeEnum.PBIP:
return new PbipFile(pbiFilePath);
case PbiFile.PBIFileTypeEnum.PBIPReport:
return new PbipReportFile(pbiFilePath);
default:
throw new PBIXInspectorException(string.Format("Could not determine the extension of PBI file with path \"{0}\".", pbiFilePath));
}
}
}
}
18 changes: 18 additions & 0 deletions PBIXInspectorTests/CLIArgsUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,24 @@ public void TestCLIArgsUtilsResolvePbiFilePathInput3()
Assert.IsTrue(resolvedPath == expectedPath);
}

[Test]
public void TestCLIArgsUtilsResolvePbipFilePathThrows()
{
string inputPath = @"C:\TEMP\VisOps\Sales - custom colours.pbip";

ArgumentException ex = Assert.Throws<ArgumentException>(
() => ArgsUtils.ResolvePbiFilePathInput(inputPath));
}

[Test]
public void TestCLIArgsUtilsResolvePbirFilePathThrows()
{
string inputPath = @"C:\TEMP\VisOps\Sales - custom colours.Report\definition.pbir";

ArgumentException ex = Assert.Throws<ArgumentException>(
() => ArgsUtils.ResolvePbiFilePathInput(inputPath));
}

[Test]
public void TestCLIArgsUtilsSuccess_FormatsOption()
{
Expand Down
36 changes: 36 additions & 0 deletions PBIXInspectorTests/PbiFileUtilsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma warning disable CS8602

using PBIXInspectorLibrary;

namespace PBIXInspectorTests
{
public class PbiFileUtilsTests
{
[Test]
public void PbiFileUtilsThrows()
{
PbiFile pbiFile = null;
string pbiFilePath = null;
PBIXInspectorException ex = Assert.Throws<PBIXInspectorException>(
() => pbiFile = PbiFileUtils.InitPbiFile(pbiFilePath));
}

[Test]
public void PbiFileUtilsThrows2()
{
PbiFile pbiFile = null;
string pbiFilePath = string.Empty;
PBIXInspectorException ex = Assert.Throws<PBIXInspectorException>(
() => pbiFile = PbiFileUtils.InitPbiFile(pbiFilePath));
}

[Test]
public void PbiFileUtilsThrows3()
{
PbiFile pbiFile = null;
string pbiFilePath = "myreport.xxxx";
PBIXInspectorException ex = Assert.Throws<PBIXInspectorException>(
() => pbiFile = PbiFileUtils.InitPbiFile(pbiFilePath));
}
}
}
17 changes: 9 additions & 8 deletions PBIXInspectorWinForm/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ namespace PBIXInspectorWinForm
{
public partial class MainForm : Form
{
private static Args _args;


public MainForm()
{
InitializeComponent();
Expand Down Expand Up @@ -112,17 +111,19 @@ private void chckUseTempFiles_CheckedChanged(object sender, EventArgs e)
private void btnRun_Click(object sender, EventArgs e)
{
Clear();

btnRun.Enabled = false;
var pbiFilePath = ArgsUtils.ResolvePbiFilePathInput(this.txtPBIDesktopFile.Text);

var pbiFilePath = this.txtPBIDesktopFile.Text;
var rulesFilePath = this.txtRulesFilePath.Text;
var outputPath = this.txtOutputDirPath.Text;
var verboseString = this.chckVerbose.Checked.ToString();
var formatsString = string.Concat(this.chckJsonOutput.Checked ? "JSON" : string.Empty, ",", this.chckHTMLOutput.Checked ? "HTML" : string.Empty);
_args = new Args { PBIFilePath = pbiFilePath, RulesFilePath = rulesFilePath, OutputPath = outputPath, FormatsString = formatsString, VerboseString = verboseString };
var verbose = this.chckVerbose.Checked;
var jsonOutput = this.chckJsonOutput.Checked;
var htmlOutput = this.chckHTMLOutput.Checked;

Main.Run(_args);
btnRun.Enabled = true;
Main.Run(pbiFilePath, rulesFilePath, outputPath, verbose, jsonOutput, htmlOutput);

btnRun.Enabled = true;
}

internal void Clear()
Expand Down
2 changes: 2 additions & 0 deletions PBIXInspectorWinLibrary/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public static class Constants
public const string SampleRulesFilePath = @"Files\Base-rules.json";
public const string ReportPageFieldMapFilePath = @"Files\ReportPageFieldMap.json";
public const string PBIPReportJsonFileName = "report.json";
public const string PBIPFileExtension = ".pbip";
public const string PBIRFileExtension = ".pbir";
public const string TestRunHTMLTemplate = @"Files\html\TestRunTemplate.html";
public const string PBIInspectorPNG = @"Files\icon\pbiinspector.png";
public const string TestRunHTMLFileName = "TestRun.html";
Expand Down
11 changes: 11 additions & 0 deletions PBIXInspectorWinLibrary/Files/html/TestRunTemplate.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ <h6 class="border-bottom pb-2 mb-0">Results</h6>
"html": [{ "<>": "strong", "class": "d-block text-gray-dark", "text": "Verbose" }, { "text": "${Verbose}" }]
}
]
},
{
"<>": "div",
"class": "d-flex text-body-secondary pt-3",
"html": [
{
"<>": "p",
"class": "pb-3 mb-0 small lh-sm",
"html": [{ "<>": "strong", "class": "d-block text-gray-dark", "text": "Results stats" }, { "text": function () { if (this.Results != null) { return "Results count: " + this.Results.length } else { return "No results were found."} } }]
}
]
}
]
};
Expand Down
58 changes: 39 additions & 19 deletions PBIXInspectorWinLibrary/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ private set
}
}

public static void Run(string pbiFilePath, string rulesFilePath, string outputPath, bool verbose, bool jsonOutput, bool htmlOutput)
{
var formatsString = string.Concat(jsonOutput ? "JSON" : string.Empty, ",", htmlOutput ? "HTML" : string.Empty);
var verboseString = verbose.ToString();

string resolvedPbiFilePath = string.Empty;

try
{
resolvedPbiFilePath = ArgsUtils.ResolvePbiFilePathInput(pbiFilePath);
}
catch (ArgumentException e)
{
OnMessageIssued(MessageTypeEnum.Error, e.Message);
}

var args = new Args { PBIFilePath = resolvedPbiFilePath, RulesFilePath = rulesFilePath, OutputPath = outputPath, FormatsString = formatsString, VerboseString = verboseString };

Run(args);
}

public static void Run(Args args)
{
Expand All @@ -54,12 +74,12 @@ public static void Run(Args args)

try
{
_insp = new Inspector(_args.PBIFilePath, _args.RulesFilePath);
_insp = new Inspector(Main._args.PBIFilePath, Main._args.RulesFilePath);
_insp.MessageIssued += Insp_MessageIssued;

_testResults = _insp.Inspect().Where(_ => (!_args.Verbose && !_.Pass) || (_args.Verbose));
_testResults = _insp.Inspect().Where(_ => (!Main._args.Verbose && !_.Pass) || (Main._args.Verbose));

if (_args.CONSOLEOutput || _args.ADOOutput)
if (Main._args.CONSOLEOutput || Main._args.ADOOutput)
{
foreach (var result in _testResults)
{
Expand All @@ -70,43 +90,43 @@ public static void Run(Args args)
}

//Ensure output dir exists
if (!_args.ADOOutput && (_args.JSONOutput || _args.HTMLOutput || _args.PNGOutput))
if (!Main._args.ADOOutput && (Main._args.JSONOutput || Main._args.HTMLOutput || Main._args.PNGOutput))
{
if (!Directory.Exists(_args.OutputDirPath))
if (!Directory.Exists(Main._args.OutputDirPath))
{
Directory.CreateDirectory(_args.OutputDirPath);
Directory.CreateDirectory(Main._args.OutputDirPath);
}
}

if (!_args.ADOOutput && (_args.JSONOutput || _args.HTMLOutput))
if (!Main._args.ADOOutput && (Main._args.JSONOutput || Main._args.HTMLOutput))
{
var outputFilePath = string.Empty;
var pbiFileNameWOextension = Path.GetFileNameWithoutExtension(_args.PBIFilePath);
var pbiFileNameWOextension = Path.GetFileNameWithoutExtension(Main._args.PBIFilePath);

if (!string.IsNullOrEmpty(_args.OutputDirPath))
if (!string.IsNullOrEmpty(Main._args.OutputDirPath))
{
outputFilePath = Path.Combine(_args.OutputDirPath, string.Concat("TestRun_", pbiFileNameWOextension, ".json"));
outputFilePath = Path.Combine(Main._args.OutputDirPath, string.Concat("TestRun_", pbiFileNameWOextension, ".json"));
}
else
{
throw new ArgumentException("Directory with path \"{0}\" does not exist", _args.OutputDirPath);
throw new ArgumentException("Directory with path \"{0}\" does not exist", Main._args.OutputDirPath);
}

var testRun = new TestRun() { CompletionTime = DateTime.Now, TestedFilePath = _args.PBIFilePath, RulesFilePath = _args.RulesFilePath, Verbose = _args.Verbose, Results = _testResults };
var testRun = new TestRun() { CompletionTime = DateTime.Now, TestedFilePath = Main._args.PBIFilePath, RulesFilePath = Main._args.RulesFilePath, Verbose = Main._args.Verbose, Results = _testResults };
_jsonTestRun = JsonSerializer.Serialize(testRun);
if (_args.JSONOutput)
if (Main._args.JSONOutput)
{
OnMessageIssued(MessageTypeEnum.Information, string.Format("Writing JSON output to file at \"{0}\".", outputFilePath));
File.WriteAllText(outputFilePath, _jsonTestRun, System.Text.Encoding.UTF8);
}
}

if (!_args.ADOOutput && (_args.PNGOutput || _args.HTMLOutput))
if (!Main._args.ADOOutput && (Main._args.PNGOutput || Main._args.HTMLOutput))
{
_fieldMapInsp = new Inspector(_args.PBIFilePath, Constants.ReportPageFieldMapFilePath);
_fieldMapInsp = new Inspector(Main._args.PBIFilePath, Constants.ReportPageFieldMapFilePath);
_fieldMapResults = _fieldMapInsp.Inspect();

var outputPNGDirPath = Path.Combine(_args.OutputDirPath, Constants.PNGOutputDir);
var outputPNGDirPath = Path.Combine(Main._args.OutputDirPath, Constants.PNGOutputDir);

if (Directory.Exists(outputPNGDirPath))
{
Expand All @@ -121,7 +141,7 @@ public static void Run(Args args)
ImageUtils.DrawReportPages(_fieldMapResults, _testResults, outputPNGDirPath);
}

if (!_args.ADOOutput && _args.HTMLOutput)
if (!Main._args.ADOOutput && Main._args.HTMLOutput)
{
string pbiinspectorlogobase64 = string.Concat(Constants.Base64ImgPrefix, ImageUtils.ConvertBitmapToBase64(Constants.PBIInspectorPNG));
//string nowireframebase64 = string.Concat(Base64ImgPrefix, ImageUtils.ConvertBitmapToBase64(@"Files\png\nowireframe.png"));
Expand All @@ -130,13 +150,13 @@ public static void Run(Args args)
html = html.Replace(Constants.VersionPlaceholder, AppUtils.About(), StringComparison.OrdinalIgnoreCase);
html = html.Replace(Constants.JsonPlaceholder, _jsonTestRun, StringComparison.OrdinalIgnoreCase);

var outputHTMLFilePath = Path.Combine(_args.OutputDirPath, Constants.TestRunHTMLFileName);
var outputHTMLFilePath = Path.Combine(Main._args.OutputDirPath, Constants.TestRunHTMLFileName);

OnMessageIssued(MessageTypeEnum.Information, string.Format("Writing HTML output to file at \"{0}\".", outputHTMLFilePath));
File.WriteAllText(outputHTMLFilePath, html);

//Results have been written to a temporary directory so show output to user automatically.
if (_args.DeleteOutputDirOnExit)
if (Main._args.DeleteOutputDirOnExit)
{
AppUtils.WinOpen(outputHTMLFilePath);
}
Expand Down
16 changes: 13 additions & 3 deletions PBIXInspectorWinLibrary/Utils/ArgsUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,20 @@ public static Args ParseArgs(string[] args)

public static string? ResolvePbiFilePathInput(string pbiFilePath)
{
var resolvedPath = !string.IsNullOrEmpty(pbiFilePath) && pbiFilePath.ToLower().EndsWith(Constants.PBIPReportJsonFileName)
? Path.GetDirectoryName(pbiFilePath)
: pbiFilePath;
var resolvedPath = pbiFilePath;

if (!string.IsNullOrEmpty(pbiFilePath) && (pbiFilePath.ToLower().EndsWith(Constants.PBIPReportJsonFileName)))
{
resolvedPath = Path.GetDirectoryName(pbiFilePath);
}

//TODO: support PBIP file path. Need to parse the json and retrieve the report folder path.
if (!string.IsNullOrEmpty(pbiFilePath) && (pbiFilePath.ToLower().EndsWith(Constants.PBIPFileExtension)
|| pbiFilePath.ToLower().EndsWith(Constants.PBIRFileExtension)))
{
throw new ArgumentException(string.Format("PBIP and PBIR file types are not yet supported. Please specify a report.json file path instead."));
}

return resolvedPath;
}
}
Expand Down

0 comments on commit fa28eb5

Please sign in to comment.