Exemple #1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Verifies that all footnotes correspond to exactly one ORC in the vernacular
        /// Scripture and that they are in the same order as they occur in Scripture.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private void VerifyNoOrphanedFootnotes()
        {
            ScrChecksDataSource scrData = new ScrChecksDataSource(Cache);

            foreach (IScrBook book in m_scr.ScriptureBooksOS)
            {
                IEnumerator <IStFootnote> footnotes = book.FootnotesOS.GetEnumerator();
                IStFootnote currentFootnote         = (footnotes.MoveNext() ? footnotes.Current : null);

                scrData.GetText(book.CanonicalNum, 0);
                foreach (ITextToken tok in scrData.TextTokens())
                {
                    if (tok.TextType == TextType.Note)
                    {
                        if (tok.IsNoteStart)
                        {
                            Assert.IsNotNull(currentFootnote, "No more footnotes were expected in " + book.BestUIName);
                            Assert.IsTrue(((IStTxtPara)currentFootnote.ParagraphsOS[0]).Contents.Text.StartsWith(tok.Text),
                                          "Footnote ORC does not match next footnote in sequence (mismatched text)");
                            Assert.AreEqual(currentFootnote.ParagraphsOS[0].StyleName, tok.ParaStyleName,
                                            "Footnote ORC does not match next footnote in sequence (mismatched style)");
                            currentFootnote = (footnotes.MoveNext() ? footnotes.Current : null);
                        }
                    }
                    else
                    {
                        Assert.IsFalse(tok.Text.Contains(StringUtils.kszObject));
                    }
                }
                Assert.IsNull(currentFootnote);
            }
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Reads the current TE scripture project.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private List <TextTokenSubstring> ReadTEScripture()
        {
            var scrDataSource = new ScrChecksDataSource(m_cache, DirectoryFinder.TeStylesPath);

            scrDataSource.LoadException += scrDataSource_LoadException;

            Assembly asm = Assembly.LoadFile(m_scrChecksDllFile);

            if (asm == null)
            {
                return(null);
            }
            Type type = asm.GetType("SILUBS.ScriptureChecks." + m_checkToRun);

            var scrCharInventoryBldr = Activator.CreateInstance(type, scrDataSource) as IScrCheckInventory;

            if (scrCharInventoryBldr == null)
            {
                return(null);
            }

            var tokens = new List <ITextToken>();
            var scr    = m_cache.LangProject.TranslatedScriptureOA;

            if (scr == null || scr.ScriptureBooksOS.Count == 0)
            {
                return(null);
            }

            foreach (var book in scr.ScriptureBooksOS)
            {
                if (scrDataSource.GetText(book.CanonicalNum, 0))
                {
                    tokens.AddRange(scrDataSource.TextTokens());
                }
            }

            foreach (KeyValuePair <string, string> kvp in m_chkParams)
            {
                scrDataSource.SetParameterValue(kvp.Key, kvp.Value);
            }

            scrDataSource.SetParameterValue("PreferredLocale", string.Empty);

            if (tokens.Count == 0)
            {
                return(null);
            }

            return(GetTokenSubstrings(scrCharInventoryBldr, tokens));
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Reads the current TE scripture project.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private List <TextTokenSubstring> ReadTEScripture()
        {
            var scrDataSource = new ScrChecksDataSource(m_cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"),
                                                        FwDirectoryFinder.LegacyWordformingCharOverridesFile, FwDirectoryFinder.TeStylesPath);

            scrDataSource.LoadException += scrDataSource_LoadException;

            IScrCheckInventory scrCharInventoryBldr = CreateScrCharInventoryBldr(FwDirectoryFinder.BasicEditorialChecksDll,
                                                                                 scrDataSource, m_checkToRun == CheckType.Punctuation ?
                                                                                 "SILUBS.ScriptureChecks.PunctuationCheck" : "SILUBS.ScriptureChecks.CharactersCheck");

            var tokens = new List <ITextToken>();
            var scr    = m_cache.LangProject.TranslatedScriptureOA;

            if (scr == null || scr.ScriptureBooksOS.Count == 0)
            {
                return(null);
            }

            foreach (var book in scr.ScriptureBooksOS)
            {
                if (scrDataSource.GetText(book.CanonicalNum, 0))
                {
                    tokens.AddRange(scrDataSource.TextTokens());
                }
            }

            foreach (KeyValuePair <string, string> kvp in m_chkParams)
            {
                scrDataSource.SetParameterValue(kvp.Key, kvp.Value);
            }

            scrDataSource.SetParameterValue("PreferredLocale", string.Empty);

            return(tokens.Count == 0 ? null : GetTokenSubstrings(scrCharInventoryBldr, tokens));
        }
		public void GetTextTokens_ChapterStartsAndEndsMidSection()
		{

			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis");
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");

			// Section 1 starts with Chapter 1
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head1", ScrStyleNames.SectionHead);
			StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "Chapter 1 Verse 1 Text", null);
			section.AdjustReferences();

			// Section 2 starts with Chapter 1, but also contains the start of Chapter 2
			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head2", ScrStyleNames.SectionHead);
			para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "2", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "Chapter 1 Verse 2 Text", null);
			StTxtPara paraSect2Content2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "3", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "Chapter 1 Verse 3 Text ", null);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "2", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "Chapter 2 Verse 1 Text", null);
			section.AdjustReferences();

			// Section 3 starts with Chapter 2, but also contains the start of Chapter 3
			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara paraSectHead3 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head3", ScrStyleNames.SectionHead);
			StTxtPara paraSect3Content = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect3Content, "More Chapter 2 Verse 1 Text ", null);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect3Content, "2", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect3Content, "Chapter 2 Verse 2 Text ", null);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect3Content, "3", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect3Content, "Chapter 3 Verse 1 Text", null);
			section.AdjustReferences();

			Assert.IsTrue(dataSource.GetText(iExodus, 2));
			IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator();
			BCVRef expectedRef = new BCVRef(iExodus, 2, 1);
			VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, false, TextType.ChapterNumber, paraSect2Content2);
			VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect2Content2);
			VerifyToken(tokens, "Chapter 2 Verse 1 Text", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content2);
			VerifyToken(tokens, "Head3", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead3);
			VerifyToken(tokens, "More Chapter 2 Verse 1 Text ", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, true, TextType.Verse, paraSect3Content);
			expectedRef.Verse = 2;
			VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect3Content);
			VerifyToken(tokens, "Chapter 2 Verse 2 Text ", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect3Content);
			Assert.IsFalse(tokens.MoveNext());
		}
		public void GetTextTokens_LastChapter()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis");
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");

			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head1", ScrStyleNames.SectionHead);
			StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "Chapter 1 Verse 1 Text", null);
			section.AdjustReferences();

			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara paraSectHead2 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head2", ScrStyleNames.SectionHead);
			StTxtPara paraSect2Content1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "2", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Chapter 2 Verse 1 Text", null);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "2", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Chapter 2 Verse 2 Text ", null);
			StTxtPara paraSect2Content2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, "Line 1");
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "Selah", ScrStyleNames.Interlude);
			section.AdjustReferences();

			Assert.IsTrue(dataSource.GetText(iExodus, 2));
			IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator();
			BCVRef expectedRef = new BCVRef(iExodus, 2, 1);
			VerifyToken(tokens, "Head2", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead2);
			expectedRef.Chapter = 2;
			VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, true, TextType.ChapterNumber, paraSect2Content1);
			VerifyToken(tokens, "Chapter 2 Verse 1 Text", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content1);
			expectedRef.Verse = 2;
			VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect2Content1);
			VerifyToken(tokens, "Chapter 2 Verse 2 Text ", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content1);
			VerifyToken(tokens, "Selah", "Line 1", ScrStyleNames.Interlude, expectedRef, true, TextType.Verse, paraSect2Content2);
			Assert.IsFalse(tokens.MoveNext());
		}
		public void GetTextTokens_DifferentWritingSystem()
		{
			// Set valid characters for each writing system to a different set of three characters.
			// The set of valid characters will be 'ABC' for the first writing system, 'DEF' for
			// the second and so on.
			ILgWritingSystemFactory lgwsf = m_inMemoryCache.Cache.LanguageWritingSystemFactoryAccessor;
			int cWs = lgwsf.NumberOfWs;
			ArrayPtr rgWs = MarshalEx.ArrayToNative(cWs, typeof(int));
			lgwsf.GetWritingSystems(rgWs, cWs);
			int[] hvoWsArray = (int[])MarshalEx.NativeToArray(rgWs, cWs, typeof(int));
			List<string> validChars = new List<string>();
			int iWs = 0;
			int numValidChars = 3;
			for (iWs = 0; iWs < cWs; iWs++)
			{
				IWritingSystem ws = lgwsf.get_EngineOrNull(hvoWsArray[iWs]);
				StringBuilder strBldr = new StringBuilder();
				for (int iChar = 0; iChar < numValidChars; iChar++)
				{
					strBldr.Append(Encoding.ASCII.GetString(
						new byte[] { (byte)(65 + numValidChars * iWs + iChar) }));
					strBldr.Append(" ");
				}
				validChars.Add(strBldr.ToString());
				ws.ValidChars = validChars[iWs];
			}

			// Set up (minimal) Scripture data.
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");

			// Get the text (and set the valid characters for each writing system).
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			dataSource.GetText(iExodus, 1);

			// Now confirm that the valid characters for the writing systems were set correctly.
			for (iWs = 0; iWs < cWs; iWs++)
			{
				IWritingSystem ws = lgwsf.get_EngineOrNull(hvoWsArray[iWs]);
				string validCharsParam = (ws.WritingSystem == Cache.DefaultVernWs) ?
					"ValidCharacters" : "ValidCharacters_" + lgwsf.GetStrFromWs(hvoWsArray[iWs]);
				Assert.AreEqual(validChars[iWs].TrimEnd(' '), dataSource.GetParameterValue(validCharsParam));
			}
		}
		public void GetTextTokens_FirstChapter()
		{
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");

			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			IScrSection section = m_scrInMemoryCache.AddIntroSectionToMockedBook(exodus.Hvo);
			StTxtPara para = m_scrInMemoryCache.AddParaToMockedText(section.HeadingOAHvo,
				ScrStyleNames.IntroSectionHead);
			m_scrInMemoryCache.AddRunToMockedPara(para, "Everything you wanted to know about Exodus but were afraid to ask", null);
			para = m_scrInMemoryCache.AddParaToMockedText(section.ContentOAHvo,
				ScrStyleNames.IntroParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "There's not much to say, really.", null);
			section.AdjustReferences();

			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara paraSectHead1 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head1", ScrStyleNames.SectionHead);
			StTxtPara paraSect1Content = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "Chapter 1 Verse 1 Text", null);
			section.AdjustReferences();

			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head2", ScrStyleNames.SectionHead);
			para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "2", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "Chapter 2 Verse 1 Text", null);
			section.AdjustReferences();

			Assert.IsTrue(dataSource.GetText(iExodus, 1));
			IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator();
			BCVRef expectedRef = new BCVRef(iExodus, 1, 1);
			VerifyToken(tokens, "Head1", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead1);
			expectedRef = new BCVRef(iExodus, 1, 1);
			VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, true, TextType.ChapterNumber, paraSect1Content);
			VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect1Content);
			VerifyToken(tokens, "Chapter 1 Verse 1 Text", "Paragraph", string.Empty, expectedRef, false, TextType.Verse, paraSect1Content);
			Assert.IsFalse(tokens.MoveNext());
		}
		public void GetTextTokens_WholeBook()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis");
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");

			IScrSection section = m_scrInMemoryCache.AddIntroSectionToMockedBook(exodus.Hvo);
			StTxtPara paraIntroSectHead = m_scrInMemoryCache.AddParaToMockedText(section.HeadingOAHvo,
				ScrStyleNames.IntroSectionHead);
			m_scrInMemoryCache.AddRunToMockedPara(paraIntroSectHead, "Everything you wanted to know about Exodus but were afraid to ask", null);
			StTxtPara paraIntroSectContent = m_scrInMemoryCache.AddParaToMockedText(section.ContentOAHvo,
				ScrStyleNames.IntroParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraIntroSectContent, "There's not much to say, really.", null);
			section.AdjustReferences();

			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara paraSectHead1 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head1", ScrStyleNames.SectionHead);
			StTxtPara paraSect1Content = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect1Content, "Chapter 1 Verse 1 Text", null);
			section.AdjustReferences();

			section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara paraSectHead2 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Head2", ScrStyleNames.SectionHead);
			StTxtPara paraSect2Content1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "2", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Chapter 2 Verse 1 Text", null);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "2", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Chapter 2 Verse 2 Text ", null);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content1, "Wow!", "Emphasis");
			StTxtPara paraSect2Content2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, "Line 1");
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, "Selah", ScrStyleNames.Interlude);
			StFootnote footnote = m_scrInMemoryCache.AddFootnote(exodus, paraSect2Content2, 5, "This is the text of the footnote");
			m_scrInMemoryCache.AddRunToMockedPara((StTxtPara)footnote.ParagraphsOS[0], "Favorite", Cache.DefaultUserWs);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect2Content2, " or say, \"la\".", null);
			CmPicture pict;
			using (DummyFileMaker filemaker = new DummyFileMaker("junk.jpg", true))
			{
				ITsStrFactory factory = TsStrFactoryClass.Create();
				pict = new CmPicture(Cache, filemaker.Filename,
					factory.MakeString("Test picture caption", Cache.DefaultVernWs),
					StringUtils.LocalPictures);
				ITsStrBldr bldr = paraSect2Content2.Contents.UnderlyingTsString.GetBldr();
				pict.AppendPicture(Cache.DefaultVernWs, bldr);
				paraSect2Content2.Contents.UnderlyingTsString = bldr.GetString();
			}
			section.AdjustReferences();

			Assert.IsTrue(dataSource.GetText(iExodus, 0));
			IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator();
			VerifyToken(tokens, "Exodus", ScrStyleNames.MainBookTitle, string.Empty, exodus.TitleOA.ParagraphsOS[0]);
			VerifyToken(tokens, "Everything you wanted to know about Exodus but were afraid to ask", ScrStyleNames.IntroSectionHead, string.Empty, paraIntroSectHead);
			VerifyToken(tokens, "There's not much to say, really.", ScrStyleNames.IntroParagraph, string.Empty, paraIntroSectContent);
			BCVRef expectedRef = new BCVRef(iExodus, 1, 1);
			VerifyToken(tokens, "Head1", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead1);
			VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, true, TextType.ChapterNumber, paraSect1Content);
			VerifyToken(tokens, "1", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect1Content);
			VerifyToken(tokens, "Chapter 1 Verse 1 Text", "Paragraph", string.Empty, expectedRef, false, TextType.Verse, paraSect1Content);
			expectedRef.Chapter = 2;
			VerifyToken(tokens, "Head2", ScrStyleNames.SectionHead, string.Empty, expectedRef, true, TextType.Other, paraSectHead2);
			VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.ChapterNumber, expectedRef, true, TextType.ChapterNumber, paraSect2Content1);
			VerifyToken(tokens, "Chapter 2 Verse 1 Text", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content1);
			expectedRef.Verse = 2;
			VerifyToken(tokens, "2", ScrStyleNames.NormalParagraph, ScrStyleNames.VerseNumber, expectedRef, false, TextType.VerseNumber, paraSect2Content1);
			VerifyToken(tokens, "Chapter 2 Verse 2 Text ", ScrStyleNames.NormalParagraph, string.Empty, expectedRef, false, TextType.Verse, paraSect2Content1);
			VerifyToken(tokens, "Wow!", ScrStyleNames.NormalParagraph, ScrStyleNames.Emphasis, expectedRef, false, TextType.Verse, paraSect2Content1);
			VerifyToken(tokens, "Selah", "Line 1", ScrStyleNames.Interlude, expectedRef, true, TextType.Verse, paraSect2Content2);
			VerifyToken(tokens, "This is the text of the footnote", ScrStyleNames.NormalFootnoteParagraph, string.Empty,
				expectedRef, true, TextType.Note, footnote.ParagraphsOS[0]);
			VerifyToken(tokens, "Favorite", ScrStyleNames.NormalFootnoteParagraph, string.Empty, expectedRef,
				expectedRef, false, TextType.Note, "en", footnote.ParagraphsOS[0], (int)StTxtPara.StTxtParaTags.kflidContents);
			VerifyToken(tokens, " or say, \"la\".", "Line 1", string.Empty, expectedRef, false, TextType.Verse, paraSect2Content2);
			VerifyToken(tokens, "Test picture caption", ScrStyleNames.Figure, string.Empty, expectedRef, expectedRef, true, TextType.PictureCaption, null,
				pict, (int)CmPicture.CmPictureTags.kflidCaption);
			Assert.IsFalse(tokens.MoveNext());
		}
		public void RecordError_DuplicateAfterAdjustingReference()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			tok.MissingStartRef = new BCVRef(tok.StartRef);
			tok.MissingStartRef.Verse++;
			tok.MissingEndRef = new BCVRef(tok.MissingStartRef);
			tok.MissingEndRef.Verse++; // this simulates missing two verses
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 1, 1, "3"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"First run of check should add error annotation");

			annotations.NotesOS[0].ResolutionStatus = NoteStatus.Closed;

			// Need a new token because the one above has already gotten changed.
			tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			tok.MissingStartRef = new BCVRef(tok.StartRef);
			tok.MissingStartRef.Verse++;
			tok.MissingEndRef = new BCVRef(tok.MissingStartRef);
			tok.MissingEndRef.Verse++; // this simulates missing two verses
			check.m_ErrorsToReport.Clear();
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 1, 1, "3"));

			dataSource.RunCheck(check);
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"Second run of check shouldn't create a duplicate.");
			Assert.AreEqual(NoteStatus.Closed, annotations.NotesOS[0].ResolutionStatus,
				"Annotation should still be resolved/closed (ignored).");
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Verifies that all footnotes correspond to exactly one ORC in the vernacular
		/// Scripture and that they are in the same order as they occur in Scripture.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private void VerifyNoOrphanedFootnotes()
		{
			ScrChecksDataSource scrData = new ScrChecksDataSource(Cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"), FwDirectoryFinder.LegacyWordformingCharOverridesFile);
			foreach (IScrBook book in m_scr.ScriptureBooksOS)
			{
				using (IEnumerator<IScrFootnote> footnotes = book.FootnotesOS.GetEnumerator())
				{
					IStFootnote currentFootnote = (footnotes.MoveNext() ? footnotes.Current : null);

					scrData.GetText(book.CanonicalNum, 0);
					foreach (ITextToken tok in scrData.TextTokens())
					{
						if (tok.TextType == TextType.Note)
						{
							if (tok.IsNoteStart)
							{
								Assert.IsNotNull(currentFootnote, "No more footnotes were expected in " + book.BestUIName);
								Assert.IsTrue(((IStTxtPara)currentFootnote.ParagraphsOS[0]).Contents.Text.StartsWith(tok.Text),
									"Footnote ORC does not match next footnote in sequence (mismatched text)");
								Assert.AreEqual(currentFootnote.ParagraphsOS[0].StyleName, tok.ParaStyleName,
									"Footnote ORC does not match next footnote in sequence (mismatched style)");
								currentFootnote = (footnotes.MoveNext() ? footnotes.Current : null);
							}
						}
						else
						{
							Assert.IsFalse(tok.Text.Contains(StringUtils.kszObject));
						}
					}
					Assert.IsNull(currentFootnote);
				}
			}
		}
		public void RecordError_NearDuplicate_DifferByCheck()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			ICmAnnotationDefn annDefnChkError = new CmAnnotationDefn(Cache,
				LangProject.kguidAnnCheckingError);
			CmAnnotationDefn errorCheck1 = new CmAnnotationDefn();
			annDefnChkError.SubPossibilitiesOS.Append(errorCheck1);
			errorCheck1.Guid = Guid.NewGuid();
			errorCheck1.Name.UserDefaultWritingSystem = "Type 1";

			CmAnnotationDefn errorCheck2 = new CmAnnotationDefn();
			annDefnChkError.SubPossibilitiesOS.Append(errorCheck2);
			errorCheck2.Guid = Guid.NewGuid();
			errorCheck2.Name.UserDefaultWritingSystem = "Type 2";

			DummyEditorialCheck check1 = new DummyEditorialCheck(errorCheck1.Guid);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check1.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "General Error"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check1);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"Check 1 should add 1 error annotation");
			IScrScriptureNote origErrorAnnotation = annotations.NotesOS[0];

			DummyEditorialCheck check2 = new DummyEditorialCheck(errorCheck2.Guid);
			check2.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "General Error"));

			dataSource.RunCheck(check2);
			Assert.AreEqual(2, annotations.NotesOS.Count,
				"Check 2 should add another error annotation.");
			Assert.IsTrue(annotations.NotesOS.Contains(origErrorAnnotation));
		}
		public void RecordError_NearDuplicate_DifferOnlyByParaHvo()
		{
			IScrBook book = m_scrInMemoryCache.AddBookToMockedScripture(1, "My Favorite Book");

			BCVRef reference = new BCVRef(1, 2, 3);

			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(book,
				Cache.DefaultVernWs, 0, reference, reference);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Message"));

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);

			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"First run of check should add 1 error annotation");
			IScrScriptureNote origErrorAnnotation = annotations.NotesOS[0];

			IScrDraft draft = m_scr.ArchivedDraftsOC.Add(new ScrDraft());
			draft.BooksOS.Append(book);

			Assert.AreEqual(0, m_scr.ScriptureBooksOS.Count);

			check.m_ErrorsToReport.Clear();
			IScrBook newBook = m_scrInMemoryCache.AddBookToMockedScripture(1, "My Favorite Book");

			tok = new DummyParaCheckingToken(newBook, Cache.DefaultVernWs, 0, reference, reference);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Message"));
			dataSource.RunCheck(check);
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"Second run of check should add another error annotation.");
			Assert.IsTrue(annotations.NotesOS.Contains(origErrorAnnotation));
			Assert.AreEqual(newBook.Hvo, annotations.NotesOS[0].BeginObjectRAHvo);
			Assert.AreEqual(newBook.Hvo, annotations.NotesOS[0].EndObjectRAHvo);
			Assert.AreEqual(reference, annotations.NotesOS[0].BeginRef);
			Assert.AreEqual(reference, annotations.NotesOS[0].EndRef);
			Assert.AreEqual(5, annotations.NotesOS[0].BeginOffset);
			Assert.AreEqual(13, annotations.NotesOS[0].EndOffset);
		}
		public void RunCheck_CorrectedErrorGetsDeleted()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Lousy message"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"First run of check should add 1 error annotation");
			IScrScriptureNote origErrorAnnotation = annotations.NotesOS[0];
			Assert.AreEqual("Lousy message",
				((StTxtPara)origErrorAnnotation.DiscussionOA.ParagraphsOS[0]).Contents.Text);

			check.m_ErrorsToReport.Clear();
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Goofy message"));
			dataSource.RunCheck(check);
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"Second run of check should delete the 'fixed' error annotation and add another error annotation.");
			IScrScriptureNote newErrorAnnotation = annotations.NotesOS[0];
			Assert.AreNotEqual(origErrorAnnotation, newErrorAnnotation);
			Assert.AreEqual("Goofy message",
				((StTxtPara)newErrorAnnotation.DiscussionOA.ParagraphsOS[0]).Contents.Text);
		}
		public void RunCheck_ScrCheckRunRecordsWithOneBookTwoChecks()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check1 = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check1.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Verbification"));
			tok = new DummyParaCheckingToken(m_scr, m_inMemoryCache.Cache.DefaultVernWs, 0);
			check1.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 26, 2, "Verbification"));

			DummyEditorialCheck check2 = new DummyEditorialCheck(kCheckId2);
			check2.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Stupid Check"));
			tok = new DummyParaCheckingToken(m_scr, m_inMemoryCache.Cache.DefaultVernWs, 0);
			check2.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 26, 2, "Stupid Check"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "The Book of David");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check1);
			dataSource.RunCheck(check2);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];

			Assert.AreEqual(2, annotations.ChkHistRecsOC.Count);
			Assert.AreEqual(4, annotations.NotesOS.Count);

			ScrCheckRun scr1 =
				new ScrCheckRun(Cache, annotations.ChkHistRecsOC.HvoArray[0]);
			ScrCheckRun scr2 =
				new ScrCheckRun(Cache, annotations.ChkHistRecsOC.HvoArray[1]);

			Assert.AreEqual(ScrCheckRunResult.Inconsistencies, scr1.Result);
			Assert.AreEqual(ScrCheckRunResult.Inconsistencies, scr2.Result);
			Assert.AreEqual(NoteStatus.Open, annotations.NotesOS[0].ResolutionStatus);
			Assert.AreEqual(NoteStatus.Open, annotations.NotesOS[1].ResolutionStatus);
			Assert.AreEqual(NoteStatus.Open, annotations.NotesOS[2].ResolutionStatus);
			Assert.AreEqual(NoteStatus.Open, annotations.NotesOS[3].ResolutionStatus);

			annotations.NotesOS[0].ResolutionStatus = NoteStatus.Closed;
			annotations.NotesOS[1].ResolutionStatus = NoteStatus.Closed;
			dataSource.RunCheck(check1);

			scr1 = new ScrCheckRun(Cache, annotations.ChkHistRecsOC.HvoArray[0]);
			scr2 = new ScrCheckRun(Cache, annotations.ChkHistRecsOC.HvoArray[1]);
			Assert.AreEqual(ScrCheckRunResult.IgnoredInconsistencies, scr1.Result);
			Assert.AreEqual(ScrCheckRunResult.Inconsistencies, scr2.Result);
		}
		public void RunCheck_ScrCheckRunRecordsWithFixedInconsistency()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Verbification"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "The Book of David");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];

			Assert.AreEqual(1, annotations.ChkHistRecsOC.Count);
			Assert.AreEqual(1, annotations.NotesOS.Count);

			ScrCheckRun scr =
				new ScrCheckRun(Cache, annotations.ChkHistRecsOC.HvoArray[0]);

			Assert.AreEqual(ScrCheckRunResult.Inconsistencies, scr.Result);
			Assert.AreEqual(NoteStatus.Open, annotations.NotesOS[0].ResolutionStatus);

			check.m_ErrorsToReport.Clear();
			dataSource.RunCheck(check);

			Assert.AreEqual(1, annotations.ChkHistRecsOC.Count);
			Assert.AreEqual(0, annotations.NotesOS.Count);

			scr = new ScrCheckRun(Cache, annotations.ChkHistRecsOC.HvoArray[0]);
			Assert.AreEqual(ScrCheckRunResult.NoInconsistencies, scr.Result);
		}
		public void RecordError_Duplicate_SameErrorTwiceInVerse()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Lousy message"));
			tok = new DummyParaCheckingToken(m_scr, m_inMemoryCache.Cache.DefaultVernWs, 0);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 26, 2, "Lousy message"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(2, annotations.NotesOS.Count,
				"First run of check should add two error annotations");
			Assert.AreEqual(5, annotations.NotesOS[0].BeginOffset);
			Assert.AreEqual(26, annotations.NotesOS[1].BeginOffset);
			Assert.AreEqual(28, annotations.NotesOS[1].EndOffset);

			// Change the offset of the second error (but the text is still the same at that ich, so the
			// error's key will be the same).
			check.m_ErrorsToReport[1].m_ichStart = 37;

			dataSource.RunCheck(check);
			Assert.AreEqual(2, annotations.NotesOS.Count,
				"Second run of check shouldn't create a duplicate.");
			Assert.AreEqual(5, annotations.NotesOS[0].BeginOffset,
				"Offset of first annotation shouldn't change.");
			Assert.AreEqual(37, annotations.NotesOS[1].BeginOffset,
				"Begin offset of second annotation should get updated.");
			Assert.AreEqual(39, annotations.NotesOS[1].EndOffset,
				"End offset of second annotation should get updated.");
		}
		public void GetTextTokens_EmptyTsStringWithMissingWs()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");
			IScrSection section = m_scrInMemoryCache.AddIntroSectionToMockedBook(exodus.Hvo);

			// Make the heading paragraph empty, and with no writing system set
			CacheBase cachebase = m_inMemoryCache.CacheAccessor;
			StTxtPara paraIntroSectHead = new StTxtPara(Cache, cachebase.NewHvo(StTxtPara.kClassId));
			cachebase.AppendToFdoVector(section.HeadingOAHvo,
				(int)StText.StTextTags.kflidParagraphs, paraIntroSectHead.Hvo);
			cachebase.SetBasicProps(paraIntroSectHead.Hvo, section.HeadingOAHvo, (int)StTxtPara.kClassId,
				(int)StText.StTextTags.kflidParagraphs, 1);
			ITsPropsFactory propFact = TsPropsFactoryClass.Create();
			paraIntroSectHead.StyleRules = propFact.MakeProps(ScrStyleNames.IntroSectionHead, 0, 0);
			ITsStrBldr strBldr = TsStrBldrClass.Create();
			strBldr.Replace(0, 0, "", null);
			paraIntroSectHead.Contents.UnderlyingTsString = strBldr.GetString();
			cachebase.SetGuid(paraIntroSectHead.Hvo, (int)CmObjectFields.kflidCmObject_Guid, Guid.NewGuid());

			// Set up the intro section contents
			StTxtPara paraIntroSectContent = m_scrInMemoryCache.AddParaToMockedText(section.ContentOAHvo,
				ScrStyleNames.IntroParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraIntroSectContent, "There's not much to say, really.", null);
			section.AdjustReferences();

			Assert.IsTrue(dataSource.GetText(iExodus, 0));
			IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator();
			VerifyToken(tokens, "Exodus", ScrStyleNames.MainBookTitle, string.Empty, exodus.TitleOA.ParagraphsOS[0]);
			BCVRef expectedRef = new BCVRef(iExodus, 1, 0);
			VerifyToken(tokens, string.Empty, ScrStyleNames.IntroSectionHead, string.Empty, expectedRef, expectedRef,
				true, TextType.Other, null, paraIntroSectHead, (int)StTxtPara.StTxtParaTags.kflidContents);
			VerifyToken(tokens, "There's not much to say, really.", ScrStyleNames.IntroParagraph, string.Empty, paraIntroSectContent);
			Assert.IsFalse(tokens.MoveNext());
		}
		public void RecordError_Duplicate()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Lousy message"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"First run of check should add error annotation");

			dataSource.RunCheck(check);
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"Second run of check shouldn't create a duplicate.");
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Reads the current TE scripture project.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		private List<TextTokenSubstring> ReadTEScripture()
		{
			var scrDataSource = new ScrChecksDataSource(m_cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"),
				FwDirectoryFinder.LegacyWordformingCharOverridesFile, FwDirectoryFinder.TeStylesPath);

			scrDataSource.LoadException += scrDataSource_LoadException;

			IScrCheckInventory scrCharInventoryBldr = CreateScrCharInventoryBldr(FwDirectoryFinder.BasicEditorialChecksDll,
				scrDataSource, m_checkToRun == CheckType.Punctuation ?
				"SILUBS.ScriptureChecks.PunctuationCheck" : "SILUBS.ScriptureChecks.CharactersCheck");

			var tokens = new List<ITextToken>();
			var scr = m_cache.LangProject.TranslatedScriptureOA;
			if (scr == null || scr.ScriptureBooksOS.Count == 0)
				return null;

			foreach (var book in scr.ScriptureBooksOS)
			{
				if (scrDataSource.GetText(book.CanonicalNum, 0))
					tokens.AddRange(scrDataSource.TextTokens());
			}

			foreach (KeyValuePair<string, string> kvp in m_chkParams)
				scrDataSource.SetParameterValue(kvp.Key, kvp.Value);

			scrDataSource.SetParameterValue("PreferredLocale", string.Empty);

			return tokens.Count == 0 ? null : GetTokenSubstrings(scrCharInventoryBldr, tokens);
		}
		public void RecordError_NearDuplicate_DifferByCitedText()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1);
			ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0);
			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 0, 4, "Message"));

			m_scrInMemoryCache.AddBookToMockedScripture(tok.StartRef.Book, "My Favorite Book");

			dataSource.GetText(tok.StartRef.Book, 0);
			dataSource.RunCheck(check);
			IScrBookAnnotations annotations = m_scr.BookAnnotationsOS[tok.StartRef.Book - 1];
			Assert.AreEqual(1, annotations.NotesOS.Count,
				"First run of check should add 1 error annotation");
			IScrScriptureNote origErrorAnnotation = annotations.NotesOS[0];

			check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Message"));
			dataSource.RunCheck(check);
			Assert.AreEqual(2, annotations.NotesOS.Count,
				"Second run of check should add another error annotation.");
			Assert.IsTrue(annotations.NotesOS.Contains(origErrorAnnotation));
		}
		public void GetTextTokens_Chapter0()
		{
			ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache);
			int iExodus = 2;
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(iExodus, "Exodus");
			m_scrInMemoryCache.AddTitleToMockedBook(exodus.Hvo, "Exodus");

			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara paraSectHead0 = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Heading", ScrStyleNames.SectionHead);
			StTxtPara paraSect0Content = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(paraSect0Content, "0", ScrStyleNames.ChapterNumber);

			Assert.IsTrue(dataSource.GetText(iExodus, 0));
			IEnumerator<ITextToken> tokens = dataSource.TextTokens().GetEnumerator();
			VerifyToken(tokens, "Exodus", ScrStyleNames.MainBookTitle, string.Empty, exodus.TitleOA.ParagraphsOS[0]);

			// Skip the next token (the section head).
			tokens.MoveNext();

			// The chapter number should be the next token, and trying to get it shouldn't crash TE.
			tokens.MoveNext();
			ScrCheckingToken token = tokens.Current as ScrCheckingToken;
			Assert.AreEqual("0", token.Text);
			Assert.AreEqual(TextType.ChapterNumber, token.TextType);
		}