diff --git a/Src/xWorks/ConfiguredLcmGenerator.cs b/Src/xWorks/ConfiguredLcmGenerator.cs index 33297e2d37..f77d3fcec2 100644 --- a/Src/xWorks/ConfiguredLcmGenerator.cs +++ b/Src/xWorks/ConfiguredLcmGenerator.cs @@ -744,9 +744,19 @@ private static bool GetPropValueForModelField(object fieldOwner, ConfigurableDic } // Convert the contents to IEnumerable var objects = contents.Select(id => cache.LangProject.Services.GetObject(id)); - var type = objects.FirstOrDefault()?.GetType() ?? typeof(object); - var castMethod = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(type); - propertyValue = castMethod.Invoke(null, new object[] { objects }); + var firstObjType = objects.FirstOrDefault()?.GetType(); + // check that each item in objects can be cast to firstObjType + if (firstObjType != null && objects.All(o => firstObjType.IsInstanceOfType(o))) + { + var castMethod = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(firstObjType); + propertyValue = castMethod.Invoke(null, new object[] { objects }); + } + else + { + var castMethod = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(typeof(object)); + propertyValue = castMethod.Invoke(null, new object[] { objects }); + + } break; } case (int)CellarPropertyType.ReferenceAtomic: @@ -1575,7 +1585,7 @@ private static IFragment GenerateContentForCollection(object collectionField, Li else { bool first = true; - foreach (var item in collection) + foreach (object item in collection) { frag.Append(GenerateCollectionItemContent(nodeList, pubDecorator, item, collectionOwner, settings, first)); first = false; diff --git a/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTestHelpers.cs b/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTestHelpers.cs index 1e2effb8d0..9dac737497 100644 --- a/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTestHelpers.cs +++ b/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTestHelpers.cs @@ -430,21 +430,33 @@ internal static ILexExampleSentence AddExampleToSense(ILexSense sense, string co return example; } - private IMoForm AddAllomorphToEntry(ILexEntry entry) + private IMoForm AddAllomorphToEntry(ILexEntry entry, bool stem = true) { - var morphFact = Cache.ServiceLocator.GetInstance(); - var morph = morphFact.Create(); - entry.AlternateFormsOS.Add(morph); - morph.Form.set_String(m_wsFr, TsStringUtils.MakeString("Allomorph", m_wsFr)); - - // add environment to the allomorph const int stringRepresentationFlid = 5097008; var env = Cache.ServiceLocator.GetInstance().Create(); Cache.LangProject.PhonologicalDataOA.EnvironmentsOS.Add(env); - morph.PhoneEnvRC.Add(env); Cache.MainCacheAccessor.SetString(env.Hvo, stringRepresentationFlid, TsStringUtils.MakeString("phoneyEnv", m_wsEn)); - - return morph; + if (stem) + { + var morphFact = Cache.ServiceLocator.GetInstance(); + var morph = morphFact.Create(); + entry.AlternateFormsOS.Add(morph); + morph.Form.set_String(m_wsFr, TsStringUtils.MakeString("StemAllomorph", m_wsFr)); + // add environment to the stem allomorph (PhoneEnvRC is not in the common base class between stem and affix allomorphs) + morph.PhoneEnvRC.Add(env); + return morph; + } + else + { + // if not stem, then it is an affix allomorph + var morphFact = Cache.ServiceLocator.GetInstance(); + var morph = morphFact.Create(); + entry.AlternateFormsOS.Add(morph); + morph.Form.set_String(m_wsFr, TsStringUtils.MakeString("AffixAllomorph", m_wsFr)); + // add environment to the allomorph + morph.PhoneEnvRC.Add(env); + return morph; + } } internal static ICmPicture CreatePicture(LcmCache cache, bool exists = true, string caption = "caption", string ws = "en") diff --git a/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTests.cs b/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTests.cs index 80b025e8bc..e599d1d226 100644 --- a/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTests.cs +++ b/Src/xWorks/xWorksTests/ConfiguredXHTMLGeneratorTests.cs @@ -3580,15 +3580,18 @@ public void GenerateContentForEntry_EnvironmentsAndAllomorphsAreGenerated() var mainEntry = CreateInterestingLexEntry(Cache); AddAllomorphToEntry(mainEntry); + AddAllomorphToEntry(mainEntry, false); var settings = new ConfiguredLcmGenerator.GeneratorSettings(Cache, m_propertyTable, false, false, null); //SUT var result = ConfiguredLcmGenerator.GenerateContentForEntry(mainEntry, mainEntryNode, null, settings).ToString(); const string xPathThruAllomorph = "/div[@class='lexentry']/span[@class='alternateformsos']/span[@class='alternateformso']"; AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath( - xPathThruAllomorph + "/span[@class='form']/span[@lang='fr' and text()='Allomorph']", 1); + xPathThruAllomorph + "/span[@class='form']/span[@lang='fr' and text()='StemAllomorph']", 1); + AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath( + xPathThruAllomorph + "/span[@class='form']/span[@lang='fr' and text()='AffixAllomorph']", 1); AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(xPathThruAllomorph + - "/span[@class='allomorphenvironments']/span[@class='allomorphenvironment']/span[@class='stringrepresentation']/span[@lang='en' and text()='phoneyEnv']", 1); + "/span[@class='allomorphenvironments']/span[@class='allomorphenvironment']/span[@class='stringrepresentation']/span[@lang='en' and text()='phoneyEnv']", 2); } [Test]