Exemple #1
0
        private static ConfigurableDictionaryNode CreatePictureModel()
        {
            var thumbNailNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "PictureFileRA",
                CSSClassNameOverride = "picture"
            };
            var pictureNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "PicturesOfSenses",
                CSSClassNameOverride = "Pictures",
                Children             = new List <ConfigurableDictionaryNode> {
                    thumbNailNode
                }
            };
            var sensesNode = new ConfigurableDictionaryNode {
                FieldDescription = "Senses"
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                Children = new List <ConfigurableDictionaryNode> {
                    sensesNode, pictureNode
                },
                FieldDescription = "LexEntry"
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
            return(mainEntryNode);
        }
Exemple #2
0
        public void DuplicatesGroupingNodeChildrenAffectSuffixes()
        {
            var nodeToDuplicateLabel = "node";
            var nodeToDuplicate      = new ConfigurableDictionaryNode {
                Label = nodeToDuplicateLabel, LabelSuffix = null
            };
            var dupUnderGroup = new ConfigurableDictionaryNode {
                Label = nodeToDuplicateLabel, LabelSuffix = "1"
            };
            var groupingNode = new ConfigurableDictionaryNode
            {
                Label    = "groupNode", DictionaryNodeOptions = new DictionaryNodeGroupingOptions(),
                Children = new List <ConfigurableDictionaryNode> {
                    dupUnderGroup
                }
            };
            var parent = new ConfigurableDictionaryNode {
                Children = new List <ConfigurableDictionaryNode> {
                    nodeToDuplicate, groupingNode
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(parent);

            // SUT
            var duplicate  = nodeToDuplicate.DuplicateAmongSiblings();
            var inGroupDup = dupUnderGroup.DuplicateAmongSiblings();

            Assert.That(duplicate.Label, Is.EqualTo(nodeToDuplicateLabel), "should not have changed original node label");
            Assert.That(nodeToDuplicate.LabelSuffix, Is.Null, "should not have changed original node label suffix");
            Assert.That(duplicate.LabelSuffix, Is.EqualTo("2"), "(1) was used in the group, so the suffix should be 2");
            Assert.That(inGroupDup.LabelSuffix, Is.EqualTo("3"), "(2) was used in the group parent, so the suffix should be 3");
        }
Exemple #3
0
        public void BuildPathStringFromNode()
        {
            var subsenses = new ConfigurableDictionaryNode {
                Label = "Subsenses", FieldDescription = "SensesOS", ReferenceItem = "SharedSenses"
            };
            var sharedSenses = new ConfigurableDictionaryNode
            {
                Label = "SharedSenses", FieldDescription = "SensesOS", Children = new List <ConfigurableDictionaryNode> {
                    subsenses
                }
            };
            var senses = new ConfigurableDictionaryNode {
                Label = "Senses", FieldDescription = "SensesOS", ReferenceItem = "SharedSenses"
            };
            var mainEntry = new ConfigurableDictionaryNode
            {
                FieldDescription = "LexEntry", Children = new List <ConfigurableDictionaryNode> {
                    senses
                }
            };
            var model = DictionaryConfigurationModelTests.CreateSimpleSharingModel(mainEntry, sharedSenses);

            CssGeneratorTests.PopulateFieldsForTesting(model);             // PopulateFieldsForTesting populates each node's Label with its FieldDescription

            Assert.AreEqual("LexEntry > Senses > SharedSenses > Subsenses", DictionaryConfigurationMigrator.BuildPathStringFromNode(subsenses));
            Assert.AreEqual("LexEntry > Senses > Subsenses", DictionaryConfigurationMigrator.BuildPathStringFromNode(subsenses, false));
            Assert.AreEqual("LexEntry", DictionaryConfigurationMigrator.BuildPathStringFromNode(mainEntry));
        }
Exemple #4
0
        public void TryGetMasterParent()
        {
            var child      = new ConfigurableDictionaryNode();
            var sharedNode = new ConfigurableDictionaryNode {
                Label = "Shared", Children = new List <ConfigurableDictionaryNode> {
                    child
                }
            };
            var masterParent = new ConfigurableDictionaryNode {
                ReferenceItem = "Shared"
            };
            var root = new ConfigurableDictionaryNode {
                Children = new List <ConfigurableDictionaryNode> {
                    masterParent
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(DictionaryConfigurationModelTests.CreateSimpleSharingModel(root, sharedNode));

            ConfigurableDictionaryNode returnedMasterParent;

            Assert.True(child.TryGetMasterParent(out returnedMasterParent));                                                                          // SUT
            Assert.AreSame(masterParent, returnedMasterParent);
            Assert.False(masterParent.TryGetMasterParent(out returnedMasterParent), "The master parent doesn't *have* a master parent, it *is* one"); // SUT
            Assert.IsNull(returnedMasterParent, "Master Parent");
            Assert.False(root.TryGetMasterParent(out returnedMasterParent), "The root node *certainly* doesn't have a master parent");                // SUT
            Assert.IsNull(returnedMasterParent, "Root Node");
        }
        public void UploadToWebonaryExportsXhtmlAndCss()
        {
            using (var controller = SetUpController())
            {
                var mockView   = SetUpView();
                var testConfig = new Dictionary <string, DictionaryConfigurationModel>();
                mockView.Model.Configurations = testConfig;
                // Build model sufficient to generate xhtml and css
                ConfiguredXHTMLGenerator.AssemblyFile = "FDO";
                var mainHeadwordNode = new ConfigurableDictionaryNode
                {
                    FieldDescription      = "HeadWord",
                    CSSClassNameOverride  = "entry",
                    DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions {
                        Options = DictionaryDetailsControllerTests.ListOfEnabledDNOsFromStrings(new[] { "fr" })
                    },
                    Before = "MainEntry: ",
                };
                var mainEntryNode = new ConfigurableDictionaryNode
                {
                    Children = new List <ConfigurableDictionaryNode> {
                        mainHeadwordNode
                    },
                    FieldDescription = "LexEntry",
                };
                var model = new DictionaryConfigurationModel {
                    Parts = new List <ConfigurableDictionaryNode> {
                        mainEntryNode
                    }
                };
                CssGeneratorTests.PopulateFieldsForTesting(model);
                testConfig["Test Config"] = model;
                // create entry sufficient to generate xhtml and css
                var factory = Cache.ServiceLocator.GetInstance <ILexEntryFactory>();
                var entry   = factory.Create();
                var wsFr    = Cache.WritingSystemFactory.GetWsFromStr("fr");
                entry.CitationForm.set_String(wsFr, Cache.TsStrFactory.MakeString("Headword", wsFr));
                //SUT
                Assert.DoesNotThrow(() => controller.UploadToWebonary(mockView.Model, mockView));

                // The names of the files being sent to webonary are listed while logging the zip
                Assert.That(mockView.StatusStrings.Any(s => s.Contains("configured.xhtml")), "xhtml not logged as compressed");
                Assert.That(mockView.StatusStrings.Any(s => s.Contains("configured.css")), "css not logged as compressed");
            }
        }
        public void GenerateXHTMLForEntry_ReversalStringGeneratesContent()
        {
            var formNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalForm",
                Label                 = "Form",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "fr"
                        }
                    },
                    DisplayWritingSystemAbbreviations = false
                }
            };
            var reversalNode = new ConfigurableDictionaryNode
            {
                Children = new List <ConfigurableDictionaryNode> {
                    formNode
                },
                FieldDescription = "ReversalIndexEntry"
            };

            CssGeneratorTests.PopulateFieldsForTesting(reversalNode);
            var rie           = CreateInterestingFrenchReversalEntry();
            var entryHeadWord = rie.ReferringSenses.First().Entry.HeadWord;

            //SUT
            var result = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(rie, reversalNode, null, DefaultSettings);
            var reversalFormDataPath = string.Format("/div[@class='reversalindexentry']/span[@class='reversalform']/span[text()='{0}']",
                                                     TsStringUtils.Compose(rie.LongName));
            var entryDataPath = string.Format("//span[text()='{0}']", entryHeadWord.get_NormalizedForm(FwNormalizationMode.knmNFC).Text);

            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(reversalFormDataPath, 1);
            AssertThatXmlIn.String(result).HasNoMatchForXpath(entryDataPath);
        }
Exemple #7
0
        public void DuplicatesSharedGroupingNodeChildrenAffectSuffixes()
        {
            var nodeToDuplicateLabel = "node";
            var nodeToDuplicate      = new ConfigurableDictionaryNode {
                FieldDescription = nodeToDuplicateLabel
            };
            var dupUnderShardGroup = new ConfigurableDictionaryNode {
                FieldDescription = nodeToDuplicateLabel, LabelSuffix = "1"
            };
            var sharedNode = new ConfigurableDictionaryNode
            {
                Label    = "Shared",
                Children = new List <ConfigurableDictionaryNode> {
                    dupUnderShardGroup
                },
                DictionaryNodeOptions = new DictionaryNodeGroupingOptions()
            };
            var sharedGroupRefNode = new ConfigurableDictionaryNode {
                ReferenceItem = "Shared", DictionaryNodeOptions = new DictionaryNodeGroupingOptions()
            };
            var root = new ConfigurableDictionaryNode {
                Children = new List <ConfigurableDictionaryNode> {
                    sharedGroupRefNode, nodeToDuplicate
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(DictionaryConfigurationModelTests.CreateSimpleSharingModel(root, sharedNode));

            // SUT
            var duplicate  = nodeToDuplicate.DuplicateAmongSiblings();
            var inGroupDup = dupUnderShardGroup.DuplicateAmongSiblings();

            Assert.That(duplicate.Label, Is.EqualTo(nodeToDuplicateLabel), "should not have changed original node label");
            Assert.That(nodeToDuplicate.LabelSuffix, Is.Null, "should not have changed original node label suffix");
            Assert.That(duplicate.LabelSuffix, Is.EqualTo("2"), "(1) was used in the group, so the suffix should be 2");
            Assert.That(inGroupDup.LabelSuffix, Is.EqualTo("3"), "(2) was used in the group parent, so the suffix should be 3");
        }
        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);
        }
Exemple #9
0
        public void UploadToWebonaryExportsXhtmlAndCss()
        {
            using (var controller = SetUpController())
            {
                var mockView       = SetUpView();
                var testConfig     = new Dictionary <string, DictionaryConfigurationModel>();
                var reversalConfig = new Dictionary <string, DictionaryConfigurationModel>();
                mockView.Model.Configurations = testConfig;
                mockView.Model.Reversals      = reversalConfig;
                // Build model sufficient to generate xhtml and css
                ConfiguredXHTMLGenerator.AssemblyFile = "SIL.LCModel";
                var mainHeadwordNode = new ConfigurableDictionaryNode
                {
                    FieldDescription      = "HeadWord",
                    CSSClassNameOverride  = "entry",
                    DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions {
                        Options = DictionaryDetailsControllerTests.ListOfEnabledDNOsFromStrings(new[] { "fr" })
                    },
                    Before = "MainEntry: ",
                };
                var mainEntryNode = new ConfigurableDictionaryNode
                {
                    Children = new List <ConfigurableDictionaryNode> {
                        mainHeadwordNode
                    },
                    FieldDescription = "LexEntry",
                };
                var model = new DictionaryConfigurationModel {
                    Parts = new List <ConfigurableDictionaryNode> {
                        mainEntryNode
                    }
                };
                CssGeneratorTests.PopulateFieldsForTesting(model);
                testConfig["Test Config"] = model;

                var reversalFormNode = new ConfigurableDictionaryNode
                {
                    FieldDescription = "ReversalForm",
                    //DictionaryNodeOptions = CXGTests.GetWsOptionsForLanguages(new[] { "en" }),
                    DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                    {
                        WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                        Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                        {
                            new DictionaryNodeListOptions.DictionaryNodeOption {
                                Id = "en"
                            }
                        },
                        DisplayWritingSystemAbbreviations = false
                    },
                    Label = "Reversal Form"
                };
                var reversalEntryNode = new ConfigurableDictionaryNode
                {
                    Children = new List <ConfigurableDictionaryNode> {
                        reversalFormNode
                    },
                    FieldDescription = "ReversalIndexEntry"
                };
                model = new DictionaryConfigurationModel {
                    Parts = new List <ConfigurableDictionaryNode> {
                        reversalEntryNode
                    }
                };
                CssGeneratorTests.PopulateFieldsForTesting(model);
                reversalConfig["English"] = model;
                model.Label         = "English";
                model.WritingSystem = "en";
                List <string> reversalLanguage = new List <string>();
                reversalLanguage.Add("English");
                mockView.Model.SelectedReversals = reversalLanguage;

                // create entry sufficient to generate xhtml and css
                var factory = Cache.ServiceLocator.GetInstance <ILexEntryFactory>();
                var entry   = factory.Create();
                var wsFr    = Cache.WritingSystemFactory.GetWsFromStr("fr");
                entry.CitationForm.set_String(wsFr, TsStringUtils.MakeString("Headword", wsFr));
                //SUT
                Assert.DoesNotThrow(() => controller.UploadToWebonary(mockView.Model, mockView));

                // The names of the files being sent to webonary are listed while logging the zip
                Assert.That(mockView.StatusStrings.Any(s => s.Contains("configured.xhtml")), "xhtml not logged as compressed");
                Assert.That(mockView.StatusStrings.Any(s => s.Contains("configured.css")), "css not logged as compressed");
                Assert.That(mockView.StatusStrings.Any(s => s.Contains("reversal_en.xhtml")), "reversal_enxhtml not logged as compressed");
                Assert.That(mockView.StatusStrings.Any(s => s.Contains("Exporting entries for English reversal")), "English reversal not exported");
            }
        }
Exemple #10
0
        public void StoredDefaultsUpdatedFromCurrentDefaults()
        {
            var subsenses = new ConfigurableDictionaryNode {
                Label = "Subsenses", FieldDescription = "SensesOS"
            };
            var inBoth = new ConfigurableDictionaryNode
            {
                Label            = "In Both",
                FieldDescription = "Both"
            };
            var inOld = new ConfigurableDictionaryNode
            {
                Label            = "inOld",
                FieldDescription = "OnlyOld",
                Children         = new List <ConfigurableDictionaryNode> {
                    subsenses
                }
            };
            var senses = new ConfigurableDictionaryNode {
                Label = "Senses", FieldDescription = "SensesOS", Children = new List <ConfigurableDictionaryNode> {
                    inOld, inBoth
                }
            };
            var mainEntry = new ConfigurableDictionaryNode
            {
                FieldDescription = "LexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    senses
                }
            };
            var oldModel = new DictionaryConfigurationModel {
                Parts = new List <ConfigurableDictionaryNode> {
                    mainEntry
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(oldModel);             // PopulateFieldsForTesting populates each node's Label with its FieldDescription sets all isEnabled to true
            var newMain = mainEntry.DeepCloneUnderSameParent();

            newMain.Children[0].Before    = "{";
            newMain.Children[0].Between   = ",";
            newMain.Children[0].After     = "}";
            newMain.Children[0].Style     = "Stylish";
            newMain.Children[0].IsEnabled = false;
            newMain.Children[0].Children.RemoveAt(0);             // Remove inOld
            var newModel = new DictionaryConfigurationModel {
                Parts = new List <ConfigurableDictionaryNode> {
                    newMain
                }
            };

            // Verify valid starting point
            Assert.AreNotEqual("{", oldModel.Parts[0].Children[0].Before, "Invalid preconditions");
            Assert.AreNotEqual("}", oldModel.Parts[0].Children[0].After, "Invalid preconditions");
            Assert.AreNotEqual(",", oldModel.Parts[0].Children[0].Between, "Invalid preconditions");
            Assert.AreNotEqual("Stylish", oldModel.Parts[0].Children[0].Style, "Invalid preconditions");
            Assert.True(oldModel.Parts[0].Children[0].IsEnabled, "Invalid preconditions");

            DictionaryConfigurationMigrator.LoadConfigWithCurrentDefaults(oldModel, newModel);             // SUT
            Assert.AreEqual(2, oldModel.Parts[0].Children[0].Children.Count, "Old non-matching part was not retained");
            Assert.AreEqual("{", oldModel.Parts[0].Children[0].Before, "Before not copied from new defaults");
            Assert.AreEqual("}", oldModel.Parts[0].Children[0].After, "After not copied from new defaults");
            Assert.AreEqual(",", oldModel.Parts[0].Children[0].Between, "Between not copied from new defaults");
            Assert.AreEqual("Stylish", oldModel.Parts[0].Children[0].Style, "Style not copied from new defaults");
            Assert.False(oldModel.Parts[0].Children[0].IsEnabled, "IsEnabled value not copied from new defaults");
        }
        private static void CreateSubsenseModel()
        {
            var wsOpts = new DictionaryNodeWritingSystemOptions
            {
                Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                {
                    new DictionaryNodeListOptions.DictionaryNodeOption {
                        Id = "en"
                    }
                }
            };
            var DictionaryNodeSenseOptions = new DictionaryNodeSenseOptions
            {
                BeforeNumber   = "",
                AfterNumber    = ")",
                NumberStyle    = "Dictionary-SenseNumber",
                NumberingStyle = "%d",
                DisplayEachSenseInAParagraph = false,
                NumberEvenASingleSense       = true,
                ShowSharedGrammarInfoFirst   = false
            };
            var DictionaryNodeSubSenseOptions = new DictionaryNodeSenseOptions
            {
                BeforeNumber   = "",
                AfterNumber    = ")",
                NumberStyle    = "Dictionary-SenseNumber",
                NumberingStyle = "%O",
                DisplayEachSenseInAParagraph = false,
                NumberEvenASingleSense       = true,
                ShowSharedGrammarInfoFirst   = false
            };

            var glossNode = new ConfigurableDictionaryNode {
                FieldDescription = "Gloss", DictionaryNodeOptions = wsOpts
            };
            var subSenseNode = new ConfigurableDictionaryNode
            {
                FieldDescription     = "SensesOS",
                CSSClassNameOverride = "senses",
                Label = "Subsenses",
                DictionaryNodeOptions = DictionaryNodeSubSenseOptions,
                Children = new List <ConfigurableDictionaryNode> {
                    glossNode
                }
            };
            var sensesNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "SensesOS",
                CSSClassNameOverride  = "senses",
                DictionaryNodeOptions = DictionaryNodeSenseOptions,
                Children = new List <ConfigurableDictionaryNode> {
                    glossNode, subSenseNode
                }
            };

            var mainEntryNode = new ConfigurableDictionaryNode
            {
                FieldDescription = "LexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    sensesNode
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
        }
        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);
        }
        public void GenerateXHTMLForEntry_VernacularFormWithSubSensesinReversalSubEntry()
        {
            var headwordNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalName",
                Label                 = "Headword",
                CSSClassNameOverride  = "headword",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Vernacular,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "vernacular"
                        }
                    }
                }
            };
            var wsOpts = new DictionaryNodeWritingSystemOptions
            {
                WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                {
                    new DictionaryNodeListOptions.DictionaryNodeOption {
                        Id = "reversal"
                    }
                }
            };
            var glossNode = new ConfigurableDictionaryNode {
                FieldDescription = "Gloss", DictionaryNodeOptions = wsOpts
            };
            var formNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReferringSenses",
                DictionaryNodeOptions = new DictionaryNodeSenseOptions {
                    NumberingStyle = "%d", NumberEvenASingleSense = true
                },
                Children = new List <ConfigurableDictionaryNode> {
                    headwordNode, glossNode
                }
            };
            var subEntryNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "SubentriesOS",
                CSSClassNameOverride  = "subentries",
                DictionaryNodeOptions = new DictionaryNodeListAndParaOptions {
                    DisplayEachInAParagraph = true
                },
                Children = new List <ConfigurableDictionaryNode> {
                    formNode
                }
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "en"
                        }
                    },
                    DisplayWritingSystemAbbreviations = false
                },
                FieldDescription = "ReversalIndexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    subEntryNode
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
            var testEntry = CreateInterestingEnglishSubReversalEntryWithSubSense();
            //SUT
            var          xhtml          = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(testEntry, mainEntryNode, null, DefaultSettings);
            const string subSenseOneOne = "/div[@class='reversalindexentry']/span[@class='subentries']/span[@class='subentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense']/span[@class='headword']/span/span/a[text()='1.1']";

            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(subSenseOneOne, 1);
        }
        public void GenerateXHTMLForEntry_VernacularFormWithSubSenses()
        {
            var headwordNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalName",
                CSSClassNameOverride  = "headword",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Vernacular,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "vernacular"
                        }
                    }
                }
            };
            var wsOpts = new DictionaryNodeWritingSystemOptions
            {
                WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                {
                    new DictionaryNodeListOptions.DictionaryNodeOption {
                        Id = "reversal"
                    }
                }
            };
            var glossNode = new ConfigurableDictionaryNode {
                FieldDescription = "Gloss", DictionaryNodeOptions = wsOpts
            };
            var formNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReferringSenses",
                DictionaryNodeOptions = new DictionaryNodeSenseOptions {
                    NumberingStyle = "%d"
                },
                Children = new List <ConfigurableDictionaryNode> {
                    headwordNode, glossNode
                }
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "en"
                        }
                    },
                    DisplayWritingSystemAbbreviations = false
                },
                FieldDescription = "ReversalIndexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    formNode
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
            var testEntry = CreateInterestingEnglishReversalEntry();

            AddSingleSubSenseToSense(testEntry, "second gloss", m_wsEn, Cache);
            //SUT
            var xhtml = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(testEntry, mainEntryNode, null, DefaultSettings);
            // REVIEW (Hasso) 2016.03: we should probably do something about the leading space in the Sense Number Run, as it is currently in addition to the "between" space.
            const string subSenseOneOne = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense']/span[@class='headword']/span/span/a[text()='1.1']";

            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(subSenseOneOne, 1);
        }
        public void GenerateXHTMLForEntry_SenseNumbersGeneratedForMultipleReferringSenses()
        {
            var headwordNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReversalName",
                CSSClassNameOverride  = "headword",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Vernacular,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "vernacular"
                        }
                    }
                }
            };
            var glossNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "Gloss",
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "reversal"
                        }
                    }
                }
            };
            var formNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "ReferringSenses",
                DictionaryNodeOptions = new DictionaryNodeSenseOptions {
                    NumberingStyle = "%d"
                },
                Children = new List <ConfigurableDictionaryNode> {
                    headwordNode, glossNode
                }
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                DictionaryNodeOptions = new DictionaryNodeWritingSystemOptions
                {
                    WsType  = DictionaryNodeWritingSystemOptions.WritingSystemType.Reversal,
                    Options = new List <DictionaryNodeListOptions.DictionaryNodeOption>
                    {
                        new DictionaryNodeListOptions.DictionaryNodeOption {
                            Id = "en"
                        }
                    },
                    DisplayWritingSystemAbbreviations = false
                },
                FieldDescription = "ReversalIndexEntry",
                Children         = new List <ConfigurableDictionaryNode> {
                    formNode
                }
            };

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);
            var testEntry = CreateInterestingEnglishReversalEntry();

            AddSenseToReversaEntry(testEntry, "second gloss", m_wsEn, Cache);
            //SUT
            var          xhtml          = ConfiguredXHTMLGenerator.GenerateXHTMLForEntry(testEntry, mainEntryNode, null, DefaultSettings);
            const string senseNumberOne = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense' and preceding-sibling::span[@class='sensenumber' and text()='1']]//span[@lang='en' and text()='gloss']";
            const string senseNumberTwo = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense' and preceding-sibling::span[@class='sensenumber' and text()='2']]//span[@lang='en' and text()='second gloss']";

            //This assert is dependent on the specific entry data created in CreateInterestingEnglishReversalEntry
            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(senseNumberOne, 1);
            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(senseNumberTwo, 1);

            const string headwordOne = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense']/span[@class='headword']/span[@lang='fr' and child::span[@lang='fr']/a[text()='1']]/span[@lang='fr' and a[text()='Citation']]";
            const string headwordTwo = "/div[@class='reversalindexentry']/span[@class='referringsenses']/span[@class='sensecontent']/span[@class='referringsense']/span[@class='headword']/span[@lang='fr' and child::span[@lang='fr']/a[text()='2']]/span[@lang='fr' and a[text()='Citation']]";

            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(headwordOne, 1);
            AssertThatXmlIn.String(xhtml).HasSpecifiedNumberOfMatchesForXpath(headwordTwo, 1);
        }
Exemple #16
0
        public void Setup()
        {
            // Start out with a clean project configuration directory, and with a non-random name so it's easier to examine during testing.
            _projectConfigPath = Path.Combine(Path.GetTempPath(), "Dictionary");
            if (Directory.Exists(_projectConfigPath))
            {
                Directory.Delete(_projectConfigPath, true);
            }
            FileUtils.EnsureDirectoryExists(_projectConfigPath);

            _reversalProjectConfigPath = Path.Combine(Path.GetTempPath(), "ReversalIndex");
            if (Directory.Exists(_reversalProjectConfigPath))
            {
                Directory.Delete(_reversalProjectConfigPath, true);
            }
            FileUtils.EnsureDirectoryExists(_reversalProjectConfigPath);

            _controller = new DictionaryConfigurationImportController(Cache, _projectConfigPath,
                                                                      new List <DictionaryConfigurationModel>());

            _reversalController = new DictionaryConfigurationImportController(Cache, _reversalProjectConfigPath,
                                                                              new List <DictionaryConfigurationModel>());

            // Set up data for import testing.

            _zipFile         = null;
            _reversalZipFile = null;

            // Prepare configuration to export

            var configurationToExport = new DictionaryConfigurationModel
            {
                Label        = configLabel,
                Publications = new List <string> {
                    "Main Dictionary", "unknown pub 1", "unknown pub 2"
                },
                Parts = new List <ConfigurableDictionaryNode> {
                    new ConfigurableDictionaryNode {
                        FieldDescription = "LexEntry"
                    }
                },
                FilePath = Path.GetTempPath() + configFilename
            };

            CssGeneratorTests.PopulateFieldsForTesting(configurationToExport);

            _pathToConfiguration = configurationToExport.FilePath;

            // Create XML file
            configurationToExport.Save();

            // Prepare configuration to export
            var configurationReversalToExport = new DictionaryConfigurationModel
            {
                Label         = reversalConfigLabel,
                WritingSystem = "en",
                Publications  = new List <string> {
                    "Main Dictionary", "unknown pub 1", "unknown pub 2"
                },
                Parts = new List <ConfigurableDictionaryNode> {
                    new ConfigurableDictionaryNode {
                        FieldDescription = "LexEntry"
                    }
                },
                FilePath = Path.GetTempPath() + reversalConfigFilename
            };

            CssGeneratorTests.PopulateFieldsForTesting(configurationReversalToExport);
            _reversalPathToConfiguration = configurationReversalToExport.FilePath;
            configurationReversalToExport.Save();

            // Export a configuration that we know how to import

            _zipFile         = Path.GetTempFileName();
            _reversalZipFile = Path.GetTempFileName() + 1;

            // Add a test style to the cache
            NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor, () =>
            {
                var styleFactory = Cache.ServiceLocator.GetInstance <IStStyleFactory>();

                styleFactory.Create(Cache.LangProject.StylesOC, "Dictionary-Headword",
                                    ContextValues.InternalConfigureView, StructureValues.Undefined, FunctionValues.Line, true, 2, true);
                var testStyle = styleFactory.Create(Cache.LangProject.StylesOC, "TestStyle", ContextValues.InternalConfigureView, StructureValues.Undefined,
                                                    FunctionValues.Line, true, 2, false);
                testStyle.Usage.set_String(Cache.DefaultAnalWs, "Test Style");
                var normalStyle = styleFactory.Create(Cache.LangProject.StylesOC, "Normal", ContextValues.InternalConfigureView, StructureValues.Undefined,
                                                      FunctionValues.Line, false, 2, true);
                var propsBldr = TsPropsBldrClass.Create();
                propsBldr.SetIntPropValues((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, 0x2BACCA);                 // arbitrary color to create para element
                normalStyle.Rules        = propsBldr.GetTextProps();
                var styleWithNamedColors = styleFactory.Create(Cache.LangProject.StylesOC, "Nominal", ContextValues.InternalConfigureView, StructureValues.Undefined,
                                                               FunctionValues.Line, false, 2, false);
                styleWithNamedColors.BasedOnRA = normalStyle;
                propsBldr = TsPropsBldrClass.Create();
                propsBldr.SetIntPropValues((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, NamedRedBGR);
                propsBldr.SetIntPropValues((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, NamedRedBGR);
                styleWithNamedColors.Rules = propsBldr.GetTextProps();
                var styleWithCustomColors  = styleFactory.Create(Cache.LangProject.StylesOC, "Abnormal", ContextValues.InternalConfigureView, StructureValues.Undefined,
                                                                 FunctionValues.Line, false, 2, false);
                styleWithCustomColors.BasedOnRA = normalStyle;
                propsBldr = TsPropsBldrClass.Create();
                propsBldr.SetIntPropValues((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, CustomRedBGR);
                propsBldr.SetIntPropValues((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, CustomRedBGR);
                styleWithCustomColors.Rules = propsBldr.GetTextProps();
                DictionaryConfigurationManagerController.ExportConfiguration(configurationToExport, _zipFile, Cache);
                DictionaryConfigurationManagerController.ExportConfiguration(configurationReversalToExport, _reversalZipFile, Cache);
                Cache.LangProject.StylesOC.Clear();
            });
            Assert.That(File.Exists(_zipFile), "Unit test not set up right");
            Assert.That(new FileInfo(_zipFile).Length, Is.GreaterThan(0), "Unit test not set up right");

            // Clear the configuration away so we can see it gets imported

            File.Delete(_pathToConfiguration);
            Assert.That(!File.Exists(_pathToConfiguration),
                        "Unit test not set up right. Configuration should be out of the way for testing export.");
            Assert.That(_controller._configurations.All(config => config.Label != configLabel),
                        "Unit test not set up right. A config exists with the same label as the config we will import.");
            Assert.That(_controller._configurations.All(config => config.Label != configLabel),
                        "Unit test set up unexpectedly. Such a config should not be registered.");
            File.Delete(_reversalPathToConfiguration);
            Assert.That(!File.Exists(_reversalPathToConfiguration),
                        "Unit test not set up right. Reversal configuration should be out of the way for testing export.");
            Assert.That(_reversalController._configurations.All(config => config.Label != configLabel),
                        "Unit test not set up right. A reversal config exists with the same label as the reversal config we will import.");
            Assert.That(_reversalController._configurations.All(config => config.Label != configLabel),
                        "Unit test set up unexpectedly. Such a reversal config should not be registered.");
        }
        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);
        }
Exemple #18
0
        /// <summary>
        /// Creates a DictionaryConfigurationModel with one Main and one of each neeeded Minor Entry nodes, all with enabled HeadWord children
        /// </summary>
        internal static DictionaryConfigurationModel CreateInterestingConfigurationModel(LcmCache cache, PropertyTable propertyTable        = null,
                                                                                         DictionaryConfigurationModel.ConfigType configType = DictionaryConfigurationModel.ConfigType.Root)
        {
            var mainHeadwordNode = new ConfigurableDictionaryNode
            {
                FieldDescription      = "HeadWord",
                CSSClassNameOverride  = "entry",
                DictionaryNodeOptions = GetWsOptionsForLanguages(new[] { "fr" }),
                Before = "MainEntry: ",
            };
            var subEntryNode = new ConfigurableDictionaryNode
            {
                Children = new List <ConfigurableDictionaryNode> {
                    mainHeadwordNode
                },
                FieldDescription = "Subentries"
            };
            var mainEntryNode = new ConfigurableDictionaryNode
            {
                Children = new List <ConfigurableDictionaryNode> {
                    mainHeadwordNode
                },
                FieldDescription = "LexEntry"
            };

            if (configType == DictionaryConfigurationModel.ConfigType.Hybrid || configType == DictionaryConfigurationModel.ConfigType.Root)
            {
                mainEntryNode.Children.Add(subEntryNode);
            }
            if (configType == DictionaryConfigurationModel.ConfigType.Hybrid || configType == DictionaryConfigurationModel.ConfigType.Lexeme)
            {
                mainEntryNode.DictionaryNodeOptions = GetFullyEnabledListOptions(cache, DictionaryNodeListOptions.ListIds.Complex);
            }

            CssGeneratorTests.PopulateFieldsForTesting(mainEntryNode);

            var minorEntryNode = mainEntryNode.DeepCloneUnderSameParent();

            minorEntryNode.CSSClassNameOverride = "minorentry";
            minorEntryNode.Before = "MinorEntry: ";
            minorEntryNode.DictionaryNodeOptions = GetFullyEnabledListOptions(cache, DictionaryNodeListOptions.ListIds.Complex);

            var minorSecondNode = minorEntryNode.DeepCloneUnderSameParent();

            minorSecondNode.Before = "HalfStep: ";
            minorSecondNode.DictionaryNodeOptions = GetFullyEnabledListOptions(cache, DictionaryNodeListOptions.ListIds.Variant);

            var model = new DictionaryConfigurationModel
            {
                AllPublications = true,
                Parts           = new List <ConfigurableDictionaryNode> {
                    mainEntryNode, minorEntryNode, minorSecondNode
                },
                FilePath = propertyTable == null ? null : Path.Combine(DictionaryConfigurationListener.GetProjectConfigurationDirectory(propertyTable),
                                                                       "filename" + DictionaryConfigurationModel.FileExtension),
                IsRootBased = configType == DictionaryConfigurationModel.ConfigType.Root
            };

            if (configType != DictionaryConfigurationModel.ConfigType.Root)
            {
                model.Parts.Remove(minorEntryNode);
            }

            return(model);
        }