/// <summary> /// Creates a <see cref="FlexiCodeBlock"/>. /// </summary> /// <param name="blockName">The <see cref="FlexiCodeBlock"/>'s BEM block name.</param> /// <param name="title">The <see cref="FlexiCodeBlock"/>'s title.</param> /// <param name="copyIcon">The <see cref="FlexiCodeBlock"/>'s copy icon as an HTML fragment.</param> /// <param name="renderHeader">The value specifying whether to render the <see cref="FlexiCodeBlock"/>'s header.</param> /// <param name="language">The programming langauge of the <see cref="FlexiCodeBlock"/>'s code.</param> /// <param name="code">The <see cref="FlexiCodeBlock"/>'s code.</param> /// <param name="codeNumLines">The number of lines the <see cref="FlexiCodeBlock"/>'s code spans.</param> /// <param name="syntaxHighlighter">The syntax highlighter to highlight the <see cref="FlexiCodeBlock"/>'s code with.</param> /// <param name="lineNumbers">The <see cref="NumberedLineRange"/>s specifying line numbers to render.</param> /// <param name="omittedLinesIcon">The <see cref="FlexiCodeBlock"/>'s omitted lines icon as an HTML fragment.</param> /// <param name="highlightedLines">The <see cref="LineRange"/>s specifying lines to highlight.</param> /// <param name="highlightedPhrases">The <see cref="PhraseGroup"/>s specifying phrases to highlight.</param> /// <param name="renderingMode">The <see cref="FlexiCodeBlock"/>'s rendering mode.</param> /// <param name="attributes">The HTML attributes for the <see cref="FlexiCodeBlock"/>'s root element.</param> /// <param name="blockParser">The <see cref="BlockParser"/> parsing the <see cref="FlexiCodeBlock"/>.</param> public FlexiCodeBlock( string blockName, string title, string copyIcon, bool renderHeader, string language, string code, int codeNumLines, SyntaxHighlighter syntaxHighlighter, ReadOnlyCollection <NumberedLineRange> lineNumbers, string omittedLinesIcon, ReadOnlyCollection <LineRange> highlightedLines, ReadOnlyCollection <Phrase> highlightedPhrases, FlexiCodeBlockRenderingMode renderingMode, ReadOnlyDictionary <string, string> attributes, BlockParser blockParser) : base(blockParser) { BlockName = blockName; Title = title; CopyIcon = copyIcon; RenderHeader = renderHeader; Language = language; Code = code; CodeNumLines = codeNumLines; SyntaxHighlighter = syntaxHighlighter; LineNumbers = lineNumbers; OmittedLinesIcon = omittedLinesIcon; HighlightedLines = highlightedLines; HighlightedPhrases = highlightedPhrases; RenderingMode = renderingMode; Attributes = attributes; }
internal virtual void ValidateRenderingMode(FlexiCodeBlockRenderingMode renderingMode) { if (!Enum.IsDefined(typeof(FlexiCodeBlockRenderingMode), renderingMode)) { throw new OptionsException(nameof(IFlexiCodeBlockOptions.RenderingMode), string.Format(Strings.OptionsException_Shared_ValueMustBeAValidEnumValue, renderingMode, nameof(FlexiCodeBlockRenderingMode))); } }
public void ValidateRenderingMode_ThrowsOptionsExceptionIfRenderingModeIsInvalid() { // Arrange FlexiCodeBlockFactory testSubject = CreateFlexiCodeBlockFactory(); const FlexiCodeBlockRenderingMode dummyRenderingMode = (FlexiCodeBlockRenderingMode)9; // Act and assert OptionsException result = Assert.Throws <OptionsException>(() => testSubject.ValidateRenderingMode(dummyRenderingMode)); Assert.Equal(string.Format(Strings.OptionsException_OptionsException_InvalidOption, nameof(IFlexiCodeBlockOptions.RenderingMode), string.Format(Strings.OptionsException_Shared_ValueMustBeAValidEnumValue, dummyRenderingMode, nameof(FlexiCodeBlockRenderingMode))), result.Message); }
private FlexiCodeBlock CreateFlexiCodeBlock(string blockName = default, string title = default, string copyIcon = default, bool renderHeader = true, string language = default, string code = default, int codeNumLines = default, SyntaxHighlighter syntaxHighlighter = default, ReadOnlyCollection <NumberedLineRange> lineNumbers = default, string omittedLinesIcon = default, ReadOnlyCollection <LineRange> highlightedLines = default, ReadOnlyCollection <Phrase> highlightedPhrases = default, FlexiCodeBlockRenderingMode renderingMode = default, ReadOnlyDictionary <string, string> attributes = default, BlockParser blockParser = default) { return(new FlexiCodeBlock(blockName, title, copyIcon, renderHeader, language, code, codeNumLines, syntaxHighlighter, lineNumbers, omittedLinesIcon, highlightedLines, highlightedPhrases, renderingMode, attributes, blockParser)); }
public void CreateCore_CreatesFlexiCodeBlock() { // Arrange const int dummyLine = 6; const int dummyColumn = 2; var dummySpan = new SourceSpan(5, 10); const string dummyBlockName = "dummyBlockName"; const string dummyTitle = "dummyTitle"; const string dummyCopyIcon = "dummyCopyIcon"; const bool dummyRenderHeader = false; const string dummyLanguage = "dummyLanguage"; var dummyLines = new StringLineGroup(2); dummyLines.Add(new StringSlice("dummy")); dummyLines.Add(new StringSlice("line")); const SyntaxHighlighter dummySyntaxHighlighter = SyntaxHighlighter.HighlightJS; var dummyLineNumbers = new ReadOnlyCollection <NumberedLineRange>(new List <NumberedLineRange>()); var dummyResolvedLineNumbers = new ReadOnlyCollection <NumberedLineRange>(new List <NumberedLineRange>()); const string dummyOmittedLinesIcon = "dummyOmittedLinesIcon"; var dummyHighlightedLines = new ReadOnlyCollection <LineRange>(new List <LineRange>()); var dummyResolvedHighlightedLines = new ReadOnlyCollection <LineRange>(new List <LineRange>()); var dummyHighlightedPhrases = new ReadOnlyCollection <PhraseGroup>(new List <PhraseGroup>()); var dummyResolvedHighlightedPhrases = new ReadOnlyCollection <Phrase>(new List <Phrase>()); const FlexiCodeBlockRenderingMode dummyRenderingMode = FlexiCodeBlockRenderingMode.Classic; var dummyAttributes = new ReadOnlyDictionary <string, string>(new Dictionary <string, string>()); Mock <BlockParser> dummyBlockParser = _mockRepository.Create <BlockParser>(); var dummyProxyLeafBlock = new ProxyLeafBlock(null, dummyBlockParser.Object); dummyProxyLeafBlock.Line = dummyLine; dummyProxyLeafBlock.Column = dummyColumn; dummyProxyLeafBlock.Span = dummySpan; dummyProxyLeafBlock.Lines = dummyLines; BlockProcessor dummyBlockProcessor = MarkdigTypesFactory.CreateBlockProcessor(); Mock <IFlexiCodeBlockOptions> mockFlexiCodeBlockOptions = _mockRepository.Create <IFlexiCodeBlockOptions>(); mockFlexiCodeBlockOptions.Setup(f => f.BlockName).Returns(dummyBlockName); mockFlexiCodeBlockOptions.Setup(f => f.Title).Returns(dummyTitle); mockFlexiCodeBlockOptions.Setup(f => f.CopyIcon).Returns(dummyCopyIcon); mockFlexiCodeBlockOptions.Setup(f => f.RenderHeader).Returns(dummyRenderHeader); mockFlexiCodeBlockOptions.Setup(f => f.Language).Returns(dummyLanguage); mockFlexiCodeBlockOptions.Setup(f => f.SyntaxHighlighter).Returns(dummySyntaxHighlighter); mockFlexiCodeBlockOptions.Setup(f => f.LineNumbers).Returns(dummyLineNumbers); mockFlexiCodeBlockOptions.Setup(f => f.OmittedLinesIcon).Returns(dummyOmittedLinesIcon); mockFlexiCodeBlockOptions.Setup(f => f.HighlightedLines).Returns(dummyHighlightedLines); mockFlexiCodeBlockOptions.Setup(f => f.HighlightedPhrases).Returns(dummyHighlightedPhrases); mockFlexiCodeBlockOptions.Setup(f => f.RenderingMode).Returns(dummyRenderingMode); mockFlexiCodeBlockOptions.Setup(f => f.Attributes).Returns(dummyAttributes); Mock <IOptionsService <IFlexiCodeBlockOptions, IFlexiCodeBlocksExtensionOptions> > mockOptionsService = _mockRepository. Create <IOptionsService <IFlexiCodeBlockOptions, IFlexiCodeBlocksExtensionOptions> >(); mockOptionsService.Setup(f => f.CreateOptions(dummyBlockProcessor)). Returns((mockFlexiCodeBlockOptions.Object, null)); Mock <FlexiCodeBlockFactory> mockTestSubject = CreateMockFlexiCodeBlockFactory(mockOptionsService.Object); mockTestSubject.CallBase = true; mockTestSubject.Setup(t => t.ResolveBlockName(dummyBlockName)).Returns(dummyBlockName); mockTestSubject.Setup(t => t.ValidateSyntaxHighlighter(dummySyntaxHighlighter)); mockTestSubject.Setup(t => t.TryCreateSortedLineRanges(dummyLineNumbers, dummyLines.Count)).Returns(dummyResolvedLineNumbers); mockTestSubject.Setup(t => t.ValidateSortedLineNumbers(It.Is <ReadOnlyCollection <NumberedLineRange> >(lineNumbers => lineNumbers == dummyResolvedLineNumbers), dummyLines.Count)); mockTestSubject.Setup(t => t.TryCreateSortedLineRanges(dummyHighlightedLines, dummyLines.Count)).Returns(dummyResolvedHighlightedLines); mockTestSubject. Setup(t => t.ResolveHighlightedPhrases(dummyLines.ToString(), It.Is <ReadOnlyCollection <PhraseGroup> >(highlightedPhrases => highlightedPhrases == dummyHighlightedPhrases))) .Returns(dummyResolvedHighlightedPhrases); mockTestSubject.Setup(t => t.ValidateRenderingMode(dummyRenderingMode)); // Act FlexiCodeBlock result = mockTestSubject.Object.CreateCore(dummyProxyLeafBlock, dummyBlockProcessor); // Assert _mockRepository.VerifyAll(); Assert.Equal(dummyBlockName, result.BlockName); Assert.Equal(dummyTitle, result.Title); Assert.Equal(dummyCopyIcon, result.CopyIcon); Assert.Equal(dummyRenderHeader, result.RenderHeader); Assert.Equal(dummyLanguage, result.Language); Assert.Equal(dummyLines.ToString(), result.Code); Assert.Equal(dummyLines.Count, result.CodeNumLines); Assert.Equal(dummySyntaxHighlighter, result.SyntaxHighlighter); Assert.Same(dummyResolvedLineNumbers, result.LineNumbers); Assert.Same(dummyOmittedLinesIcon, result.OmittedLinesIcon); Assert.Same(dummyResolvedHighlightedLines, result.HighlightedLines); Assert.Same(dummyResolvedHighlightedPhrases, result.HighlightedPhrases); Assert.Equal(dummyRenderingMode, result.RenderingMode); Assert.Same(dummyAttributes, result.Attributes); Assert.Same(dummyBlockParser.Object, result.Parser); Assert.Equal(dummyLine, result.Line); Assert.Equal(dummyColumn, result.Column); Assert.Equal(dummySpan, result.Span); }
public static IEnumerable <object[]> FlexiCodeBlockOptions_CanBePopulated_Data() { const string dummyBlockName = "dummyBlockName"; const string dummyTitle = "dummyTitle"; const string dummyCopyIcon = "dummyCopyIcon"; const bool dummyRenderHeader = false; const string dummyLanguage = "dummyLanguage"; const SyntaxHighlighter dummySyntaxHighlighter = SyntaxHighlighter.HighlightJS; var dummyNumberedLineRange1 = new NumberedLineRange(1, startNumber: 1); var dummyLineNumbers1 = new List <NumberedLineRange> { dummyNumberedLineRange1 }; var dummyNumberedLineRange2 = new NumberedLineRange(10, 15, 8); var dummyLineNumbers2 = new List <NumberedLineRange> { dummyNumberedLineRange2 }; const string dummyOmittedLinesIcon = "dummyOmittedLinesIcon"; var dummyLineRange1 = new LineRange(1); var dummyHighlightedLines1 = new List <LineRange> { dummyLineRange1 }; var dummyLineRange2 = new LineRange(10, 15); var dummyHighlightedLines2 = new List <LineRange> { dummyLineRange2 }; const string dummyAttribute1 = "dummyAttribute1"; const string dummyAttributeValue1 = "dummyAttributeValue1"; var dummyAttributes1 = new Dictionary <string, string> { { dummyAttribute1, dummyAttributeValue1 } }; const string dummyAttribute2 = "dummyAttribute2"; const string dummyAttributeValue2 = "dummyAttributeValue2"; var dummyAttributes2 = new Dictionary <string, string> { { dummyAttribute2, dummyAttributeValue2 } }; var dummyPhraseGroup1 = new PhraseGroup("dummyRegex1", new int[] { 1, 2, 3 }); var dummyHighlightedPhrases1 = new List <PhraseGroup>() { dummyPhraseGroup1 }; var dummyPhraseGroup2 = new PhraseGroup("dummyRegex2", new int[] { -3, -2, -1 }); var dummyHighlightedPhrases2 = new List <PhraseGroup>() { dummyPhraseGroup2 }; const FlexiCodeBlockRenderingMode dummyRenderingMode = FlexiCodeBlockRenderingMode.Classic; return(new object[][] { // Populating FlexiCodeBlockOptions containing default values new object[] { new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions()), new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions( dummyBlockName, dummyTitle, dummyCopyIcon, dummyRenderHeader, dummyLanguage, dummySyntaxHighlighter, dummyLineNumbers1, dummyOmittedLinesIcon, dummyHighlightedLines1, dummyHighlightedPhrases1, dummyRenderingMode, dummyAttributes1)), $@"{{ ""{nameof(FlexiCodeBlockOptions.BlockName)}"": ""{dummyBlockName}"", ""{nameof(FlexiCodeBlockOptions.Title)}"": ""{dummyTitle}"", ""{nameof(FlexiCodeBlockOptions.CopyIcon)}"": ""{dummyCopyIcon}"", ""{nameof(FlexiCodeBlockOptions.RenderHeader)}"": ""{dummyRenderHeader}"", ""{nameof(FlexiCodeBlockOptions.Language)}"": ""{dummyLanguage}"", ""{nameof(FlexiCodeBlockOptions.SyntaxHighlighter)}"": ""{dummySyntaxHighlighter}"", ""{nameof(FlexiCodeBlockOptions.LineNumbers)}"": [ {{ ""{nameof(NumberedLineRange.StartLine)}"": {dummyNumberedLineRange1.StartLine}, ""{nameof(NumberedLineRange.EndLine)}"": {dummyNumberedLineRange1.EndLine}, ""{nameof(NumberedLineRange.StartLine)}"": {dummyNumberedLineRange1.StartLine} }} ], ""{nameof(FlexiCodeBlockOptions.OmittedLinesIcon)}"": ""{dummyOmittedLinesIcon}"", ""{nameof(FlexiCodeBlockOptions.HighlightedLines)}"": [ {{ ""{nameof(LineRange.StartLine)}"": {dummyLineRange1.StartLine}, ""{nameof(LineRange.EndLine)}"": {dummyLineRange1.EndLine} }} ], ""{nameof(FlexiCodeBlockOptions.HighlightedPhrases)}"": [ {{ ""{nameof(PhraseGroup.Regex)}"": ""{dummyPhraseGroup1.Regex}"", ""{nameof(PhraseGroup.IncludedMatches)}"": [{string.Join(",", dummyPhraseGroup1.IncludedMatches)}] }} ], ""{nameof(FlexiCodeBlockOptions.RenderingMode)}"": ""{dummyRenderingMode}"", ""{nameof(FlexiCodeBlockOptions.Attributes)}"": {{ ""{dummyAttribute1}"": ""{dummyAttributeValue1}"" }} }}" }, // Populating FlexiCodeBlockOptions with existing collections (they should be replaced instead of appended to) new object[] { new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions(lineNumbers: dummyLineNumbers1, highlightedLines: dummyHighlightedLines1, highlightedPhrases: dummyHighlightedPhrases1, attributes: dummyAttributes1)), new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions(lineNumbers: dummyLineNumbers2, highlightedLines: dummyHighlightedLines2, highlightedPhrases: dummyHighlightedPhrases2, attributes: dummyAttributes2)), $@"{{ ""{nameof(FlexiCodeBlockOptions.LineNumbers)}"": [ {{ ""{nameof(NumberedLineRange.StartLine)}"": {dummyNumberedLineRange2.StartLine}, ""{nameof(NumberedLineRange.EndLine)}"": {dummyNumberedLineRange2.EndLine}, ""{nameof(NumberedLineRange.StartNumber)}"": {dummyNumberedLineRange2.StartNumber} }} ], ""{nameof(FlexiCodeBlockOptions.HighlightedLines)}"": [ {{ ""{nameof(LineRange.StartLine)}"": {dummyLineRange2.StartLine}, ""{nameof(LineRange.EndLine)}"": {dummyLineRange2.EndLine} }} ], ""{nameof(FlexiCodeBlockOptions.HighlightedPhrases)}"": [ {{ ""{nameof(PhraseGroup.Regex)}"": ""{dummyPhraseGroup2.Regex}"", ""{nameof(PhraseGroup.IncludedMatches)}"": [{string.Join(",", dummyPhraseGroup2.IncludedMatches)}] }} ], ""{nameof(FlexiCodeBlockOptions.Attributes)}"": {{ ""{dummyAttribute2}"": ""{dummyAttributeValue2}"" }} }}" }, // Defaults for LineRanges in HighlightedLines work new object[] { new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions()), new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions(highlightedLines: dummyHighlightedLines1)), $@"{{ ""{nameof(FlexiCodeBlockOptions.HighlightedLines)}"": [{{ }}] }}" }, // Defaults for NumberedLineRanges in NumberedLineRanges work new object[] { new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions()), new SerializableWrapper <FlexiCodeBlockOptions>(new FlexiCodeBlockOptions(lineNumbers: dummyLineNumbers1)), $@"{{ ""{nameof(FlexiCodeBlockOptions.LineNumbers)}"": [{{ }}] }}" }, }); }