[TestCase(FwNormalizationMode.knmNFKD, 2, 2, "A" + COMBINING_DIAERESIS + COMBINING_MACRON)] // NFKD: no change public void get_NormalizedForm_NFSC_IsBlockedByRunBoundaries(FwNormalizationMode nm, int expectedRunCount, int expectedFirstRunLim, string expectedText) { // The macron will be in a different run; so while the first two compression // schemes produce a single character, NFSC should produce 2. string input = "A" + COMBINING_DIAERESIS + COMBINING_MACRON; var temp = new TsString(input, EnglishWS); var builder = temp.GetBldr(); // Make two runs, changing the last character builder.SetIntPropValues(2, 3, (int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); var tsInput = builder.GetString(); var actual = tsInput.get_NormalizedForm(nm); Assert.That(actual.Text, Is.EqualTo(expectedText)); Assert.That(actual.RunCount, Is.EqualTo(expectedRunCount)); var normalProps = tsInput.get_Properties(0); var boldProps = tsInput.get_Properties(1); Assert.That(actual.get_Properties(0), Is.EqualTo(normalProps)); if (expectedRunCount > 1) { Assert.That(actual.get_LimOfRun(0), Is.EqualTo(expectedFirstRunLim)); Assert.That(actual.get_Properties(1), Is.EqualTo(boldProps)); } }
[TestCase(FwNormalizationMode.knmNFKD, 6, 1, 2, expectedDecomposedTextForReorderingTests)] // NFKD: same as NFD public void get_NormalizedForm_ReorderingDiacriticsAcrossRuns_ShouldKeepCharacterPropertiesIntact( FwNormalizationMode nm, int expectedRunCount, int expectedSecondRunMin, int expectedSecondRunLim, string expectedText) { string input = "a" + COMBINING_DIAERESIS + COMBINING_DOT_BELOW + a_WITH_DIAERESIS + COMBINING_DOT_BELOW; var temp = new TsString(input, EnglishWS); var builder = temp.GetBldr(); // Make three runs, with the underdot having different props from the a and the diaeresis in each case. builder.SetIntPropValues(2, 4, (int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); var tsInput = builder.GetString(); Assert.That(tsInput.get_IsNormalizedForm(nm), Is.False); var actual = tsInput.get_NormalizedForm(nm); Assert.That(actual.Text, Is.EqualTo(expectedText)); Assert.That(actual.RunCount, Is.EqualTo(expectedRunCount)); // Second run is a good way to test that all the expected runs are in the right place Assert.That(actual.get_MinOfRun(1), Is.EqualTo(expectedSecondRunMin)); Assert.That(actual.get_LimOfRun(1), Is.EqualTo(expectedSecondRunLim)); // For all cases, first run of output should be normal, just like first run of input was // For all cases, second run of output should be bold, just like second run of input was var normalProps = tsInput.get_Properties(0); var boldProps = tsInput.get_Properties(1); Assert.That(actual.get_Properties(0), Is.EqualTo(normalProps)); Assert.That(actual.get_Properties(1), Is.EqualTo(boldProps)); Assert.That(actual.get_PropertiesAt(0), Is.EqualTo(normalProps)); Assert.That(actual.get_PropertiesAt(expectedSecondRunMin), Is.EqualTo(boldProps)); Assert.That(actual.get_PropertiesAt(expectedSecondRunLim - 1), Is.EqualTo(boldProps)); if (expectedRunCount > 2) { Assert.That(actual.get_PropertiesAt(expectedSecondRunLim), Is.EqualTo(normalProps)); } }
public void get_NormalizedForm_SimpleCases_WorkAsExpected(FwNormalizationMode nm, string expectedNormalizedText, int expectedStartIndexOfSecondRun) { TsString oneRunInput = new TsString(inputForBasicNormalizationTests, EnglishWS); ITsString actual = oneRunInput.get_NormalizedForm(nm); Assert.That(actual.Text, Is.EqualTo(expectedNormalizedText)); Assert.That(((TsString)actual).IsAlreadyNormalized(nm), Is.True); Assert.That(actual.get_IsNormalizedForm(nm), Is.True); // Make second run starting at the capital C ITsStrBldr builder = oneRunInput.GetBldr(); builder.SetIntPropValues(7, oneRunInput.Length, (int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); ITsString twoRunInput = builder.GetString(); actual = twoRunInput.get_NormalizedForm(nm); Assert.That(actual.get_MinOfRun(1), Is.EqualTo(expectedStartIndexOfSecondRun)); // This run does not split any diacritic clusters, so it should not change any normalization results (even NFSC) Assert.That(actual.Text, Is.EqualTo(expectedNormalizedText)); }
[TestCase(FwNormalizationMode.knmNFKD, 8, 1, 2, expectedDecomposedTextForUnderdotTests)] // NFKD: same as NFD public void get_NormalizedForm_MultipleInterveningRuns_CombinesOrReordersCorrectly( FwNormalizationMode nm, int expectedRunCount, int expectedSecondRunMin, int expectedSecondRunLim, string expectedText) { string input = "a" + COMBINING_DIAERESIS + COMBINING_DIAERESIS + COMBINING_DIAERESIS + COMBINING_DOT_BELOW + a_WITH_DIAERESIS + COMBINING_DOT_BELOW; var temp = new TsString(input, EnglishWS); var builder = temp.GetBldr(); // Make five total runs in the builder, so that the first underdot will have to reorder "past" multiple intervening runs builder.SetIntPropValues(1, 2, (int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)FwTextColor.kclrRed); builder.SetIntPropValues(2, 3, (int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)FwTextColor.kclrGreen); builder.SetIntPropValues(3, 4, (int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)FwTextColor.kclrBlue); builder.SetIntPropValues(4, 6, (int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); var tsInput = builder.GetString(); Assert.That(tsInput.get_IsNormalizedForm(nm), Is.False); var actual = tsInput.get_NormalizedForm(nm); Assert.That(actual.Text, Is.EqualTo(expectedText)); Assert.That(actual.RunCount, Is.EqualTo(expectedRunCount)); // Second run is a good way to test that all the expected runs are in the right place Assert.That(actual.get_MinOfRun(1), Is.EqualTo(expectedSecondRunMin)); Assert.That(actual.get_LimOfRun(1), Is.EqualTo(expectedSecondRunLim)); // For all cases, output should have runs in order normal, bold // For all cases except NFC and NFKC, the red, green and blue runs should be preserved var normalProps = tsInput.get_Properties(0); var redProps = tsInput.get_Properties(1); var greenProps = tsInput.get_Properties(2); var blueProps = tsInput.get_Properties(3); var boldProps = tsInput.get_Properties(4); Assert.That(actual.get_PropertiesAt(0), Is.EqualTo(normalProps)); Assert.That(actual.get_Properties(0), Is.EqualTo(normalProps)); Assert.That(actual.get_Properties(1), Is.EqualTo(boldProps)); if (expectedRunCount > 2) // NFC and NFKC will remove the red/green/blue runs { Assert.That(actual.get_Properties(2), Is.EqualTo(redProps)); Assert.That(actual.get_Properties(3), Is.EqualTo(greenProps)); Assert.That(actual.get_Properties(4), Is.EqualTo(blueProps)); } }
public void NfdAndFixOffsets_WithStackedDiacriticsThatDoNotOverlapRunBoundaries_FixesOffsetsCorrectly() { // This test is copied over verbatim from the old C++ unit tests string input = "Stacked diacritics: We" + // 0..21 COMBINING_DOUBLE_ACUTE_ACCENT + COMBINING_RING_BELOW + COMBINING_GRAVE_ACCENT_BELOW + // 22..24 "lc" + COMBINING_LEFT_TACK_BELOW + COMBINING_MINUS_SIGN_BELOW + // 25..28 o_WITH_CIRCUMFLEX + "o" + // 29..30 (+1) "m" + COMBINING_SEAGULL_BELOW + COMBINING_GRAVE_ACCENT + COMBINING_DIAERESIS + //31..34 COMBINING_MACRON + //35 e_WITH_GRAVE + //36 (+1) " to" + COMBINING_DIAERESIS + COMBINING_CIRCUMFLEX_ACCENT + //37..41 " Wo" + COMBINING_DOT_ABOVE + COMBINING_INVERTED_BREVE + //42..46 "r" + COMBINING_SQUARE_BELOW + //47..48 "l" + COMBINING_TILDE + //49..50 "d" + COMBINING_DOWN_TACK_BELOW + COMBINING_TILDE_BELOW + //51..53 "a" + COMBINING_DIAERESIS + COMBINING_DOT_BELOW + //54..56 a_WITH_DIAERESIS + COMBINING_DOT_BELOW + //57..58 (+1) "d" + COMBINING_ACUTE_ACCENT_BELOW + //59..60 "!"; //61 var temp = new TsString(input, EnglishWS); var builder = temp.GetBldr(); // Make two runs, to make things interesting builder.SetIntPropValues(0, 30, (int)FwTextPropType.ktptFontSize, (int)FwTextPropVar.ktpvMilliPoint, 20000); builder.SetIntPropValues(30, input.Length, (int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)FwTextColor.kclrGreen); var tsInput = (TsString)builder.GetString(); int[] origOffsets = { 30, 33, 49, 57, 0, 21, 29, input.Length - 1, 36, 37, 54, 55, 56, 58, 62 }; int[] expectedOffsets = { 31, 34, 51, 59, 0, 21, 29, input.Length - 1 + 3, 37, 39, 56, 58, 57, 60, 65 }; ITsString nfd; int[] actualOffsets; using (ArrayPtr nativeOffsets = ConvertToNativeArray(origOffsets)) { tsInput.NfdAndFixOffsets(out nfd, nativeOffsets, origOffsets.Length); actualOffsets = ConvertToManagedArray(nativeOffsets, origOffsets.Length); } CollectionAssert.AreEqual(expectedOffsets, actualOffsets); // Verify that the characters at the new offsets are still the "same" characters that were at the old offsets // "Same" because some offsets pointed to composed characters, and we expect to find the base character at the new offset for (int i = 0; i < origOffsets.Length; i++) { if (origOffsets[i] == input.Length) { continue; } int oldOffset = origOffsets[i]; int newOffset = actualOffsets[i]; char oldCh = input[oldOffset]; char newCh = nfd.Text[newOffset]; char expectedCh = oldCh; // Three offsets pointed to composed characters, which should be matched to the base character in the output if (oldCh == '\u00e4') // 'ä' { expectedCh = 'a'; } if (oldCh == '\u00f4') // 'ô' { expectedCh = 'o'; } if (oldCh == '\u00e8') // 'è' { expectedCh = 'e'; } Assert.That(newCh, Is.EqualTo(expectedCh), String.Format("Old char '{0}' (U+{1:X4}) at {2} should match new char '{3}' (U+{4:X4}) at {5}, but didn't match.", oldCh, (int)oldCh, oldOffset, newCh, newOffset, (int)newCh)); } }
public void GetBldr_TwoRuns_ReturnsBldrWithCorrectData() { TsString tss = CreateTwoRunString(); Assert.That(tss.GetBldr().GetString(), Is.EqualTo(tss)); }