public void GetMessageInlines_RendersTwoLinksAndHandlesLinkAtTheEnd() { const string message = @"The quick [brown fox](1) jumps over the [lazy dog](2)"; var link1 = new Hyperlink(); link1.Tag = 1; link1.Inlines.Add(new Run("brown fox")); var link2 = new Hyperlink(); link2.Tag = 2; link2.Inlines.Add(new Run("lazy dog")); var expected = new List <Inline> { new Run("The quick "), link1, new Run(" jumps over the "), link2, }; var actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); VerifyHyperlink(expected[3], actual[3]); }
public void GetMessageInlines_RendersWebLinkWithBackslashesInLinkText() { const string url = "http://example.com"; string message = $@"The file [..\directory\file.cpp]({url}) has a problem."; var link = new Hyperlink(); link.Tag = new Uri(url, UriKind.Absolute); link.Inlines.Add(new Run(@"..\directory\file.cpp")); var expected = new List <Inline> { new Run("The file "), link, new Run(" has a problem."), }; List <Inline> actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); }
public void GetMessageInlines_RendersWebLink() { const string url = "http://example.com"; string message = $"The quick [brown fox]({url}) jumps over the lazy dog."; var link = new Hyperlink(); link.Tag = new Uri(url, UriKind.Absolute); link.Inlines.Add(new Run("brown fox")); var expected = new List <Inline> { new Run("The quick "), link, new Run(" jumps over the lazy dog."), }; List <Inline> actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); }
public void GetMessageInlines_RendersOneLinkPlusLiteralBrackets() { const string message = @"The quick [brown fox](1) jumps over the \[lazy dog\]."; var link = new Hyperlink { Tag = 1 }; link.Inlines.Add(new Run("brown fox")); var expected = new List <Inline> { new Run("The quick "), link, new Run(" jumps over the [lazy dog]."), }; List <Inline> actual = SdkUIUtilities.GetMessageInlines(message, clickHandler: this.Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); }
public void SarifSnapshot_GetMessageEmbeddedLinkInlines_TwoLinksAndEndsWithLink() { string message = @"The quick [brown fox](1) jumps over the [lazy dog](2)"; var link1 = new Hyperlink(); link1.Tag = new Tuple <int, int>(1, 1); link1.Inlines.Add(new Run("brown fox")); var link2 = new Hyperlink(); link2.Tag = new Tuple <int, int>(1, 2); link2.Inlines.Add(new Run("lazy dog")); var expected = new List <Inline> { new Run("The quick "), link1, new Run(" jumps over the "), link2 }; var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); VerifyHyperlink(expected[3], actual[3]); }
public void GetMessageInlines_DoesNotGenerateLinkForEscapedBrackets() { string message = @"The quick \[brown fox\] jumps over the lazy dog."; // Because there are no embedded links, we shouldn't get anything back var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click); actual.Count.Should().Be(0); }
public void SarifSnapshot_GetMessageEmbeddedLinkInlines_ZeroLinksEscapedBrackets() { string message = @"The quick \[brown fox\] jumps over the lazy dog."; var expected = new List <Inline> { new Run("The quick [brown fox] jumps over the lazy dog.") }; var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click); VerifyTextRun(expected[0], actual[0]); }
public void SarifSnapshot_GetMessageEmbeddedLinkInlines_OneLinkPlusEscapedBrackets() { string message = @"The quick [brown fox](1) jumps over the \[lazy dog\]."; var link = new Hyperlink(); link.Tag = new Tuple <int, int>(1, 1); link.Inlines.Add(new Run("brown fox")); var expected = new List <Inline> { new Run("The quick "), link, new Run(" jumps over the [lazy dog].") }; var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); }
public void GetMessageInlines_RendersOneLink() { string message = @"The quick [brown fox](1) jumps over the lazy dog."; var link = new Hyperlink(); link.Tag = new Tuple <int, object>(1, 1); link.Inlines.Add(new Run("brown fox")); var expected = new List <Inline> { new Run("The quick "), link, new Run(" jumps over the lazy dog.") }; var actual = SdkUIUtilities.GetMessageInlines(message, index: 1, clickHandler: Hyperlink_Click); actual.Count.Should().Be(expected.Count); VerifyTextRun(expected[0], actual[0]); VerifyHyperlink(expected[1], actual[1]); VerifyTextRun(expected[2], actual[2]); }
public override bool TryGetValue(int index, string columnName, out object content) { content = null; if ((index >= 0) && (index < _errors.Count)) { SarifErrorListItem error = _errors[index]; if (columnName == StandardTableKeyNames2.TextInlines) { string message = error.Message; List <Inline> inlines = SdkUIUtilities.GetMessageInlines(message, index, ErrorListInlineLink_Click); if (inlines.Count > 0) { content = inlines; } } else if (columnName == StandardTableKeyNames.DocumentName) { content = FilePath; } else if (columnName == StandardTableKeyNames.ErrorCategory) { content = error.Category; } else if (columnName == StandardTableKeyNames.Line) { // The error list assumes the line number provided will be zero based and adds one before displaying the value. // i.e. if we pass 5, the error list will display 6. // Subtract one from the line number so the error list displays the correct value. int lineNumber = error.LineNumber - 1; content = lineNumber; } else if (columnName == StandardTableKeyNames.Column) { content = error.ColumnNumber; } else if (columnName == StandardTableKeyNames.Text) { content = SdkUIUtilities.UnescapeBrackets(error.ShortMessage); } else if (columnName == StandardTableKeyNames.FullText) { if (error.HasDetailsContent) { content = SdkUIUtilities.UnescapeBrackets(error.Message); } } else if (columnName == StandardTableKeyNames.ErrorSeverity) { content = GetSeverity(error.Level); } else if (columnName == StandardTableKeyNames.Priority) { content = GetSeverity(error.Level) == __VSERRORCATEGORY.EC_ERROR ? vsTaskPriority.vsTaskPriorityHigh : vsTaskPriority.vsTaskPriorityMedium; } else if (columnName == StandardTableKeyNames.ErrorSource) { content = ErrorSource.Build; } else if (columnName == StandardTableKeyNames.BuildTool) { content = error.Tool.Name; } else if (columnName == StandardTableKeyNames.ErrorCode) { if (error.Rule != null) { content = error.Rule.Id; } } else if (columnName == StandardTableKeyNames.ProjectName) { content = error.ProjectName; } else if (columnName == StandardTableKeyNames.HelpLink) { string url = null; if (!string.IsNullOrEmpty(error.HelpLink)) { url = error.HelpLink; } if (url != null) { content = Uri.EscapeUriString(url); } } else if (columnName == StandardTableKeyNames.ErrorCodeToolTip) { if (error.Rule != null) { content = error.Rule.Id + ":" + error.Rule.Name; } } else if (columnName == "suppressionstatus" || columnName == "suppressionstate" || columnName == "suppression") { content = error.VSSuppressionState.ToString(); } } return(content != null); }
public SarifResultTableEntry(SarifErrorListItem error) { this.Identity = error.GetHashCode(); this.Error = error; // Set the data that's fast to retrieve into the dictionary of values. this.columnKeyToContent[StandardTableKeyNames.DocumentName] = this.Error.FileName; this.columnKeyToContent[StandardTableKeyNames.ErrorCategory] = this.Error.Category; // The error list assumes the line number provided will be zero based and adds one before displaying the value. // i.e. if we pass 5, the error list will display 6. // Subtract one from the line number so the error list displays the correct value. this.columnKeyToContent[StandardTableKeyNames.Line] = this.Error.LineNumber - 1; this.columnKeyToContent[StandardTableKeyNames.Column] = this.Error.ColumnNumber - 1; this.columnKeyToContent[StandardTableKeyNames.ErrorSeverity] = GetSeverity(this.Error.Level); this.columnKeyToContent[StandardTableKeyNames.Priority] = GetSeverity(this.Error.Level) == __VSERRORCATEGORY.EC_ERROR ? vsTaskPriority.vsTaskPriorityHigh : vsTaskPriority.vsTaskPriorityMedium; this.columnKeyToContent[StandardTableKeyNames.ErrorSource] = ErrorSource.Build; this.columnKeyToContent[StandardTableKeyNames.BuildTool] = this.Error.Tool?.Name; if (this.Error.Rule != null) { this.columnKeyToContent[StandardTableKeyNames.ErrorCode] = this.Error.Rule.Id; this.columnKeyToContent[StandardTableKeyNames.ErrorCodeToolTip] = string.IsNullOrEmpty(this.Error.Rule.Name) ? this.Error.Rule.Id : this.Error.Rule.Id + "." + this.Error.Rule.Name; } this.columnKeyToContent[StandardTableKeyNames.ProjectName] = this.Error.ProjectName; string supressionState = this.Error.VSSuppressionState.ToString(); this.columnKeyToContent[SuppressionStateColumnName] = supressionState; // Anything that's a bit more complex, we will make a "lazy" value and evaluate // it when it's asked for. // In WPF all the content elements including Inlines can only have one parent element. // If the Inlines are binded to multiple elements, only 1 can show the Inlines. // Create duplicated message inline objects for ErrorList table entry since // Error.MessageInlines is already binded to an element in SARIF explorer. this.columnKeyToContent[StandardTableKeyNames2.TextInlines] = new Lazy <object>(() => this.Error.MessageInlines?.Any() == true ? SdkUIUtilities.GetMessageInlines(this.Error.ShortMessage, this.Error.MessageInlineLink_Click) : null); this.columnKeyToContent[FullTextInlinesColumnName] = new Lazy <object>(() => this.Error.MessageInlines?.Any() == true ? SdkUIUtilities.GetMessageInlines(this.Error.RawMessage, this.Error.MessageInlineLink_Click) : null); this.columnKeyToContent[StandardTableKeyNames.Text] = new Lazy <object>(() => SdkUIUtilities.UnescapeBrackets(this.Error.ShortMessage)); this.columnKeyToContent[StandardTableKeyNames.FullText] = new Lazy <object>(() => this.Error.HasDetailsContent ? SdkUIUtilities.UnescapeBrackets(this.Error.Message) : null); this.columnKeyToContent[StandardTableKeyNames.HelpLink] = new Lazy <object>(() => !string.IsNullOrEmpty(this.Error.HelpLink) ? Uri.EscapeUriString(this.Error.HelpLink) : null); }
public SarifResultTableEntry(SarifErrorListItem error) { this.Identity = error.GetHashCode(); this.Error = error; // Set the data that's fast to retrieve into the dictionary of values. this.columnKeyToContent[StandardTableKeyNames.DocumentName] = this.Error.FileName; this.columnKeyToContent[StandardTableKeyNames.ErrorCategory] = this.Error.Category; // The error list assumes the line number provided will be zero based and adds one before displaying the value. // i.e. if we pass 5, the error list will display 6. // Subtract one from the line number so the error list displays the correct value. this.columnKeyToContent[StandardTableKeyNames.Line] = this.Error.LineNumber - 1; this.columnKeyToContent[StandardTableKeyNames.Column] = this.Error.ColumnNumber; this.columnKeyToContent[StandardTableKeyNames.ErrorSeverity] = GetSeverity(this.Error.Level); this.columnKeyToContent[StandardTableKeyNames.Priority] = GetSeverity(this.Error.Level) == __VSERRORCATEGORY.EC_ERROR ? vsTaskPriority.vsTaskPriorityHigh : vsTaskPriority.vsTaskPriorityMedium; this.columnKeyToContent[StandardTableKeyNames.ErrorSource] = ErrorSource.Build; this.columnKeyToContent[StandardTableKeyNames.BuildTool] = this.Error.Tool?.Name; if (this.Error.Rule != null) { this.columnKeyToContent[StandardTableKeyNames.ErrorCode] = this.Error.Rule.Id; this.columnKeyToContent[StandardTableKeyNames.ErrorCodeToolTip] = string.IsNullOrEmpty(this.Error.Rule.Name) ? this.Error.Rule.Id : this.Error.Rule.Id + "." + this.Error.Rule.Name; } this.columnKeyToContent[StandardTableKeyNames.ProjectName] = this.Error.ProjectName; string supressionState = this.Error.VSSuppressionState.ToString(); this.columnKeyToContent[SuppressionStateColumnName] = supressionState; // Anything that's a bit more complex, we will make a "lazy" value and evaluate // it when it's asked for. this.columnKeyToContent[StandardTableKeyNames2.TextInlines] = new Lazy <object>(() => { string message = this.Error.Message; List <Inline> inlines = SdkUIUtilities.GetMessageInlines(message, this.ErrorListInlineLink_Click); if (inlines.Count > 0) { return(inlines); } return(null); }); this.columnKeyToContent[StandardTableKeyNames.Text] = new Lazy <object>(() => { return(SdkUIUtilities.UnescapeBrackets(this.Error.ShortMessage)); }); this.columnKeyToContent[StandardTableKeyNames.FullText] = new Lazy <object>(() => { if (this.Error.HasDetailsContent) { return(SdkUIUtilities.UnescapeBrackets(this.Error.Message)); } return(null); }); this.columnKeyToContent[StandardTableKeyNames.HelpLink] = new Lazy <object>(() => { return(!string.IsNullOrEmpty(this.Error.HelpLink) ? Uri.EscapeUriString(this.Error.HelpLink) : null); }); }