private static void AddSenseToReversaEntry(IReversalIndexEntry riEntry, string gloss, int wsId, FdoCache cache)
        {
            var entry = CXGTests.CreateInterestingLexEntry(cache);

            entry.SensesOS.First().ReversalEntriesRC.Add(riEntry);
            entry.SensesOS[0].Gloss.set_String(wsId, gloss);
        }
        private IReversalIndexEntry CreateInterestingFrenchReversalEntry()
        {
            var entry    = CXGTests.CreateInterestingLexEntry(Cache);
            var revIndex = Cache.ServiceLocator.GetInstance <IReversalIndexRepository>().FindOrCreateIndexForWs(m_wsFr);
            var riEntry  = revIndex.FindOrCreateReversalEntry("intéressant");

            entry.SensesOS.First().ReversalEntriesRC.Add(riEntry);
            return(riEntry);
        }
        private IReversalIndexEntry CreateInterestingEnglishReversalEntry(string reversalForm       = "ReversalForm",
                                                                          string vernacularHeadword = "Citation", string analysisGloss = "gloss")
        {
            var entry    = CXGTests.CreateInterestingLexEntry(Cache, vernacularHeadword, analysisGloss);
            var revIndex = Cache.ServiceLocator.GetInstance <IReversalIndexRepository>().FindOrCreateIndexForWs(m_wsEn);
            var riEntry  = revIndex.FindOrCreateReversalEntry(reversalForm);

            entry.SensesOS.First().ReversalEntriesRC.Add(riEntry);
            return(riEntry);
        }
        private static void AddSingleSubSenseToSense(IReversalIndexEntry riEntry, string gloss, int wsId, FdoCache cache)
        {
            CreateSubsenseModel();
            var entry = CXGTests.CreateInterestingLexEntry(cache);
            var sense = entry.SensesOS.First();

            sense.Gloss.set_String(wsId, cache.TsStrFactory.MakeString(gloss, wsId));
            var subSensesOne = sense.Cache.ServiceLocator.GetInstance <ILexSenseFactory>().Create();

            sense.SensesOS.Add(subSensesOne);
            var subGloss = "subgloss ";

            subSensesOne.Gloss.set_String(wsId, cache.TsStrFactory.MakeString(subGloss + "1.1", wsId));
            entry.SensesOS[0].SensesOS[0].Gloss.set_String(wsId, subGloss);
            entry.SensesOS.First().SensesOS[0].ReversalEntriesRC.Add(riEntry);
        }
        public void GenerateXHTMLForEntry_PrimaryEntryReferencesWork_VariantFormOfSense()
        {
            var mainRevEntryNode = PreparePrimaryEntryReferencesConfigSetup();
            var reversalEntry    = CreateInterestingEnglishReversalEntry("speechRevForm", "parol", "speech:gloss");
            var variantEntry     = reversalEntry.ReferringSenses.First().Owner as ILexEntry;
            var paroleEntry      = CXGTests.CreateInterestingLexEntry(Cache, "parole", "speech");

            CXGTests.CreateVariantForm(Cache, paroleEntry.SensesOS[0], variantEntry, "Spelling Variant");
            //SUT
            var          result       = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(reversalEntry, mainRevEntryNode, null, DefaultSettings);
            const string refTypeXpath = entryRefTypeXpath + "/span[@class='abbreviation']/span[@lang='en' and text()='sp. var. of']";

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(refTypeXpath, 1);
            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(refHeadwordXpath, 1);
            const string glossOrSummDefXpath = primaryEntryXpath + "/span[@class='glossorsummary']/span[@lang='en' and text()='speech']";

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(glossOrSummDefXpath, 1);
        }
        public void GenerateXHTMLForEntry_PrimaryEntryReferencesWork_ComplexFormOfEntry()
        {
            var mainRevEntryNode = PreparePrimaryEntryReferencesConfigSetup();
            var reversalEntry    = CreateInterestingEnglishReversalEntry("spokesmanRevForm", "porte-parole", "spokesman:gloss");
            var referringSense   = reversalEntry.ReferringSenses.First();
            var paroleEntry      = CXGTests.CreateInterestingLexEntry(Cache, "parole", "speech");

            paroleEntry.SummaryDefinition.SetAnalysisDefaultWritingSystem("summDefn");
            CXGTests.CreateComplexForm(Cache, paroleEntry, referringSense.Owner as ILexEntry, true);
            //SUT
            var          result        = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(reversalEntry, mainRevEntryNode, null, DefaultSettings);
            const string headwordXpath = referringSenseXpath + "/span[@class='headword']/span[@lang='fr']//a[text()='porte-parole']";

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(headwordXpath, 1);
            const string refTypeXpath = entryRefTypeXpath + "/span[@class='abbreviation']/span[@lang='en' and text()='comp. of']";

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(refTypeXpath, 1);
            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(refHeadwordXpath, 1);
            const string glossOrSummDefXpath = primaryEntryXpath + "/span[@class='glossorsummary']/span[@lang='en' and text()='summDefn']";

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(glossOrSummDefXpath, 1);
        }
        public void GenerateXHTMLForEntry_PrimaryEntryReferences_Ordered()
        {
            var mainRevEntryNode = PreparePrimaryEntryReferencesConfigSetup();

            var reversalEntry = CreateInterestingEnglishReversalEntry();
            var primaryEntry  = reversalEntry.ReferringSenses.First().Entry;
            var refer1        = CXGTests.CreateInterestingLexEntry(Cache, "Component Entry", "CompEntry Sense");
            var refer2        = CXGTests.CreateInterestingLexEntry(Cache, "Variant Entry");
            var refer3        = CXGTests.CreateInterestingLexEntry(Cache, "CompSense Entry", "Component Sense").SensesOS.First();
            var refer4        = CXGTests.CreateInterestingLexEntry(Cache, "Invariant Entry");
            var refer5        = CXGTests.CreateInterestingLexEntry(Cache, "Variante Entrie");

            using (CXGTests.CreateComplexForm(Cache, refer3, primaryEntry, new Guid("00000000-0000-0000-cccc-000000000000"), true))             // Compound
                using (CXGTests.CreateVariantForm(Cache, refer2, primaryEntry, new Guid("00000000-0000-0000-bbbb-000000000000"), "Free Variant"))
                    using (CXGTests.CreateComplexForm(Cache, refer1, primaryEntry, new Guid("00000000-0000-0000-aaaa-000000000000"), true))     // Compound
                        using (CXGTests.CreateVariantForm(Cache, refer4, primaryEntry, new Guid("00000000-0000-0000-dddd-000000000000"), null)) // no Variant Type
                            using (CXGTests.CreateVariantForm(Cache, refer5, primaryEntry, new Guid("00000000-0000-0000-eeee-000000000000"), "Spelling Variant"))
                            {
                                var result   = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(reversalEntry, mainRevEntryNode, null, DefaultSettings); // SUT
                                var assertIt = AssertThatXmlIn.String(result);
                                assertIt.HasSpecifiedNumberOfMatchesForXpath(entryRefTypeXpath, 3);                                                    // should be one Complex Form Type and two Variant Types.
                                const string headwordBit = "/span[@class='headword']/span[@lang='fr']/a[text()='{1}']";
                                const string entryRefWithSiblingXpath = entryRefsXpath + "/span[@class='mainentryref' and preceding-sibling::";
                                const string typeAndHeadwordXpath     = entryRefWithSiblingXpath
                                                                        + entryRefTypeBit + "/span[@class='abbreviation']/span[@lang='en' and text()='{0}']]" + primaryLexemeBit + headwordBit;
                                var adjacentHeadwordXpath = entryRefWithSiblingXpath
                                                            + "span[@class='mainentryref']" + primaryLexemeBit + headwordBit.Replace("{1}", "{0}") + "]" + primaryLexemeBit + headwordBit;
                                // check for proper headings on each referenced headword
                                assertIt.HasSpecifiedNumberOfMatchesForXpath(string.Format(typeAndHeadwordXpath, "comp. of", "Component Entry"), 1);
                                assertIt.HasSpecifiedNumberOfMatchesForXpath(string.Format(adjacentHeadwordXpath, "Component Entry", "CompSense Entry"), 1); // ordered within heading
                                assertIt.HasSpecifiedNumberOfMatchesForXpath(string.Format(typeAndHeadwordXpath, "fr. var. of", "Variant Entry"), 1);
                                assertIt.HasSpecifiedNumberOfMatchesForXpath(string.Format(typeAndHeadwordXpath, "sp. var. of", "Variante Entrie"), 1);
                                // verify there is no heading on the typeless variant
                                assertIt.HasNoMatchForXpath(string.Format(entryRefWithSiblingXpath + "span]" + primaryLexemeBit + headwordBit, null, "Invariant Entry"),
                                                            message: "Invariant Entry is the only typeless entry ref; it should not have any preceding siblings (Types or other Entry Refs)");
                            }
        }
        public void GenerateXHTMLForEntry_LexemeFormConfigurationGeneratesCorrectResult()
        {
            var reversalFormNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalForm",
                DictionaryNodeOptions = CXGTests.GetWsOptionsForLanguages(new [] { "en" }),
                Label = "Reversal Form"
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                Children = new List <ConfigurableDictionaryNode> {
                    reversalFormNode
                },
                FieldDescription = "ReversalIndexEntry"
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
            var entry = CreateInterestingEnglishReversalEntry();
            //SUT
            string       result        = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(entry, mainEntryNode, null, DefaultSettings);
            const string frenchLexForm = "/div[@class='reversalindexentry']/span[@class='reversalform']/span[@lang='en' and text()='ReversalForm']";

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(frenchLexForm, 1);
        }
        public void GenerateXHTMLForEntry_SameGramInfoCollapsesOnDemand()
        {
            var defOrGlossNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "DefinitionOrGloss",
                Between               = " ",
                After                 = " ",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    DisplayWritingSystemAbbreviations = false,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption> {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "reversal"
                        }
                    }
                },
                Children = new List <ConfigurableDictionaryNode>()
            };
            var catInfoNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "MLPartOfSpeech",
                CSSClassNameOverride = "partofspeech",
                Between = " ",
                After   = " ",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    DisplayWritingSystemAbbreviations = false,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption> {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "reversal"
                        }
                    }
                },
                Children = new List <ConfigurableDictionaryNode>()
            };
            var gramInfoNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "MorphoSyntaxAnalysisRA",
                CSSClassNameOverride = "morphosyntaxanalysis",
                After    = " ",
                Style    = "Dictionary-Contrasting",
                Children = new List <ConfigurableDictionaryNode> {
                    catInfoNode
                }
            };
            var headwordNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalName",
                Between               = " ",
                After                 = " ",
                StyleType             = ConfigurableDictionaryNode.StyleTypes.Character,
                Style                 = "Reversal-Vernacular",
                CSSClassNameOverride  = "headword",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType = DictionaryNodeWritingSystemOptions.WritingSystemType.Vernacular,
                    DisplayWritingSystemAbbreviations = false,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption> {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "vernacular"
                        }
                    }
                },
                Children = new List <ConfigurableDictionaryNode>()
            };
            var vernFormNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReferringSenses",
                Between               = "; ",
                After                 = " ",
                DictionaryNodeOptions = new DictionaryNodeSenseOptions
                {
                    NumberStyle                  = "Dictionary-SenseNumber",
                    AfterNumber                  = ") ",
                    NumberingStyle               = "%d",
                    NumberEvenASingleSense       = false,
                    ShowSharedGrammarInfoFirst   = true,
                    DisplayEachSenseInAParagraph = false
                },
                Children = new List <ConfigurableDictionaryNode> {
                    headwordNode, gramInfoNode, defOrGlossNode
                }
            };
            var formNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalForm",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    DisplayWritingSystemAbbreviations = false,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption> {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "reversal"
                        }
                    }
                },
                Children = new List <ConfigurableDictionaryNode>()
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                FieldDescription = "ReversalIndexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    formNode, vernFormNode
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
            var settings = DefaultSettings;

            var noun     = CreatePartOfSpeech("noun", "n");
            var verb     = CreatePartOfSpeech("verb", "v");
            var revIndex = Cache.ServiceLocator.GetInstance <IReversalIndexRepository>().FindOrCreateIndexForWs(m_wsEn);

            var entry1 = CXGTests.CreateInterestingLexEntry(Cache);

            entry1.CitationForm.set_String(m_wsFr, "premier");
            entry1.SensesOS.First().Gloss.set_String(m_wsEn, "first");
            var msa1 = Cache.ServiceLocator.GetInstance <IMoStemMsaFactory>().Create();

            entry1.MorphoSyntaxAnalysesOC.Add(msa1);
            msa1.PartOfSpeechRA = noun;
            entry1.SensesOS.First().MorphoSyntaxAnalysisRA = msa1;

            var entry2 = CXGTests.CreateInterestingLexEntry(Cache);

            entry2.CitationForm.set_String(m_wsFr, "primary");
            entry2.SensesOS.First().Gloss.set_String(m_wsEn, "first");
            var msa2 = Cache.ServiceLocator.GetInstance <IMoStemMsaFactory>().Create();

            entry2.MorphoSyntaxAnalysesOC.Add(msa2);
            msa2.PartOfSpeechRA = noun;
            entry2.SensesOS.First().MorphoSyntaxAnalysisRA = msa2;

            var testEntry = revIndex.FindOrCreateReversalEntry("first");

            entry1.SensesOS.First().ReversalEntriesRC.Add(testEntry);
            entry2.SensesOS.First().ReversalEntriesRC.Add(testEntry);

            var xhtml = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(testEntry, mainEntryNode, null, settings);

            // check that the sense gram info appears once before the rest of the sense information.
            Assert.IsNotNullOrEmpty(xhtml);
            const string sharedGramInfo   = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sharedgrammaticalinfo']/span[@class='morphosyntaxanalysis']/span[@class='partofspeech']/span[@lang='en' and text()='n']";
            const string separateGramInfo = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense']/span[@class='morphosyntaxanalysis']/span[@class='partofspeech']/span[@lang='en']";

            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(sharedGramInfo, 1);
            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(separateGramInfo, 0);

            var msa2a = Cache.ServiceLocator.GetInstance <IMoStemMsaFactory>().Create();

            entry2.MorphoSyntaxAnalysesOC.Add(msa2a);
            msa2a.PartOfSpeechRA = verb;
            entry2.SensesOS.First().MorphoSyntaxAnalysisRA = msa2a;
            xhtml = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(testEntry, mainEntryNode, null, settings);
            // check that the sense gram info appears separately for both senses.
            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(sharedGramInfo, 0);
            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(separateGramInfo, 2);
        }
        private static ConfigurableDictionaryNode PreparePrimaryEntryReferencesConfigSetup()
        {
            var abbrNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "Abbreviation",
                DictionaryNodeOptions = CXGTests.GetWsOptionsForLanguages(new[] { "analysis" })
            };
            var typeNode = new ConfigurableDictionaryNode
            {
                FieldDescription = "EntryTypes",
                Children         = new List <ConfigurableDictionaryNode> {
                    abbrNode
                },
            };
            var refHeadwordNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "HeadWord",
                CSSClassNameOverride  = "headword",
                DictionaryNodeOptions = CXGTests.GetWsOptionsForLanguages(new[] { "vernacular" }),
                Label = "Referenced Headword"
            };
            var glossOrSummaryNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "GlossOrSummary",
                DictionaryNodeOptions = CXGTests.GetWsOptionsForLanguages(new[] { "analysis" }),
                Label = "Gloss (or Summary Definition)"
            };
            var primaryEntryNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "PrimarySensesOrEntries",
                CSSClassNameOverride = "primarylexemes",
                Children             = new List <ConfigurableDictionaryNode> {
                    refHeadwordNode, glossOrSummaryNode
                },
                Label = "Primary Entry(s)"
            };
            var primaryEntryRefNode = new ConfigurableDictionaryNode
            {
                FieldDescription = "MainEntryRefs",
                Children         = new List <ConfigurableDictionaryNode> {
                    typeNode, primaryEntryNode
                },
                Label = "Primary Entry References"
            };
            var headWordNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "ReversalName",
                CSSClassNameOverride = "headword",
                Label = "Referenced Headword",
                DictionaryNodeOptions = CXGTests.GetWsOptionsForLanguages(new[] { "vernacular" })
            };
            var referencedSensesNode = new ConfigurableDictionaryNode
            {
                FieldDescription = "ReferringSenses",
                Children         = new List <ConfigurableDictionaryNode> {
                    headWordNode, primaryEntryRefNode
                },
                DictionaryNodeOptions = new DictionaryNodeSenseOptions
                {
                    NumberingStyle = "Dictionary-SenseNumber",
                    DisplayEachSenseInAParagraph = false,
                    ShowSharedGrammarInfoFirst   = false
                },
                Label = "Referenced Senses"
            };
            var mainRevEntryNode = new ConfigurableDictionaryNode
            {
                Children = new List <ConfigurableDictionaryNode> {
                    referencedSensesNode
                },
                FieldDescription     = "ReversalIndexEntry",
                CSSClassNameOverride = "reversalindexentry"
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainRevEntryNode);
            return(mainRevEntryNode);
        }