public void MergeNeutralOnLoadTest()
        {
            var manager = new DynamicResourceManager("KGySoft.CoreLibraries.Resources.TestCompiledResource", GetType().Assembly, resXBaseName)
            {
                AutoSave   = AutoSaveOptions.None,
                AutoAppend = AutoAppendOptions.AppendLastNeutralCulture | AutoAppendOptions.AppendOnLoad
            };

            string key = "TestString";

            // retrieving hu with merge
            var rsinv = manager.GetExpandoResourceSet(inv);
            var rshu  = manager.GetExpandoResourceSet(hu, ResourceSetRetrieval.LoadIfExists, true); // this will not create a new rs

            Assert.AreSame(rsinv, rshu);
            Assert.IsFalse(rshu.GetString(key).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
            rshu = manager.GetExpandoResourceSet(hu, ResourceSetRetrieval.CreateIfNotExists, true); // but this will, and performs merge, too
            Assert.AreNotSame(rsinv, rshu);
            Assert.IsTrue(rshu.GetString(key).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

            if (huRunic == null)
            {
#if NETFRAMEWORK
                Assert.Inconclusive("To run the tests in this class with full functionality, administrator rights are required");
#endif
                return;
            }

            // hu is proxied in descendants, too.
            Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
            Assert.AreSame(rshu, manager.GetExpandoResourceSet(huRunicHULowland, ResourceSetRetrieval.GetIfAlreadyLoaded, false));

            // now hu-Runic is proxied in descendants, content is copied from hu
            manager.AutoAppend = AutoAppendOptions.AppendFirstNeutralCulture | AutoAppendOptions.AppendOnLoad;
            Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
            Assert.AreNotSame(rshu, manager.GetExpandoResourceSet(huRunicHULowland, ResourceSetRetrieval.GetIfAlreadyLoaded, false));
            Assert.AreSame(manager.GetExpandoResourceSet(huRunic, ResourceSetRetrieval.GetIfAlreadyLoaded, false), manager.GetExpandoResourceSet(huRunicHULowland, ResourceSetRetrieval.GetIfAlreadyLoaded, false));

            // now hu is not proxied, specifics are proxy of hu-Runic
            manager.ReleaseAllResources();
            Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
            Assert.IsNull(manager.GetExpandoResourceSet(hu, ResourceSetRetrieval.GetIfAlreadyLoaded, false));
            Assert.AreSame(manager.GetExpandoResourceSet(huRunic, ResourceSetRetrieval.GetIfAlreadyLoaded, false), manager.GetExpandoResourceSet(huRunicHULowland, ResourceSetRetrieval.GetIfAlreadyLoaded, false));

            // now every neutral is merged
            manager.ReleaseAllResources();
            manager.AutoAppend = AutoAppendOptions.AppendNeutralCultures | AutoAppendOptions.AppendOnLoad;
            Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
            rsinv = manager.GetExpandoResourceSet(inv);
            rshu  = manager.GetExpandoResourceSet(hu);
            var rshuRunic = manager.GetExpandoResourceSet(huRunic);
            Assert.AreNotSame(rsinv, rshu);
            Assert.AreNotSame(rshu, rshuRunic);

            // The string will be prefixed even if retrieved as an object
            manager.ReleaseAllResources();
            Assert.IsTrue(((string)manager.GetObject(key, huRunicHULowland)).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
        }
        public void MergeNeutralTest()
        {
            var manager = new DynamicResourceManager("KGySoft.CoreLibraries.Resources.TestCompiledResource", GetType().Assembly, resXBaseName)
            {
                AutoSave   = AutoSaveOptions.None,
                AutoAppend = AutoAppendOptions.AppendLastNeutralCulture
            };
            string key    = "TestString";
            string custom = "custom";

            if (huRunic != null)
            {
                // creating proxies
                Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

                // this will widen append so proxies are not trustworthy anymore
                manager.AutoAppend = AutoAppendOptions.AppendFirstNeutralCulture;
                Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

                // the result will come from proxy eventually
                manager.AutoAppend = AutoAppendOptions.AppendNeutralCultures;
                Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

                // this will merge multiple resources
                manager.ReleaseAllResources();
                Assert.IsTrue(manager.GetString(key, huRunicHULowland).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

                // inserting explicitly into a proxy parent: it will be retrieved via proxy child, too
                manager.SetObject(key, custom, huRunicHU);
                Assert.AreEqual(custom, manager.GetString(key, huRunicHULowland));

                // The string will be prefixed even if retrieved as an object
                manager.ReleaseAllResources();
                Assert.IsTrue(((string)manager.GetObject(key, huRunicHULowland)).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));
                return;
            }

            // ---basic tests: no admin rights or not .NET Framework---

            // creating proxies
            Assert.IsTrue(manager.GetString(key, huHU).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

            // this will widen append so proxies are not trustworthy anymore
            manager.AutoAppend = AutoAppendOptions.AppendFirstNeutralCulture;
            Assert.IsTrue(manager.GetString(key, huHU).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

            // the result will come from proxy eventually
            manager.AutoAppend = AutoAppendOptions.AppendNeutralCultures;
            Assert.IsTrue(manager.GetString(key, huHU).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

            // this would merge multiple resources but now we have one neutral (.NET Framework with admin rights needed)
            manager.ReleaseAllResources();
            Assert.IsTrue(manager.GetString(key, huHU).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

            // inserting explicitly into a proxy parent: it will be retrieved via proxy child, too
            manager.SetObject(key, custom, hu);
            Assert.AreEqual(custom, manager.GetString(key, huHU));

            // The string will be prefixed even if retrieved as an object
            manager.ReleaseAllResources();
            Assert.IsTrue(((string)manager.GetObject(key, huHU)).StartsWith(LanguageSettings.UntranslatedResourcePrefix, StringComparison.Ordinal));

#if NETFRAMEWORK
            Assert.Inconclusive("To run the tests in this class with full functionality, administrator rights are required");
#endif
        }
        public void GetUnknownTest()
        {
            // This is a non-existing resource so MissingManifestResourceException should be thrown by default
            var manager = new DynamicResourceManager(GetType())
            {
                AutoSave       = AutoSaveOptions.None,
                AutoAppend     = AutoAppendOptions.AppendNeutralCultures,
                ThrowException = true
            };

            string key = "unknown";

            // Exception is thrown through base HRM
            Throws <MissingManifestResourceException>(() => manager.GetString(key, inv));

            // Due to possible append options, exception is thrown through derived DRM
            // For the neutral en culture a resource set is created during the traversal
            Throws <MissingManifestResourceException>(() => manager.GetString(key, enUS));
            Assert.IsNull(manager.GetResourceSet(enUS, false, false));
            Assert.IsNotNull(manager.GetResourceSet(en, false, false));

            // Exception is not thrown any more. Instead, a new resource is automatically added
            manager.AutoAppend = AutoAppendOptions.AddUnknownToInvariantCulture;
            manager.ReleaseAllResources();

            Assert.IsTrue(manager.GetString(key, inv).StartsWith(LanguageSettings.UnknownResourcePrefix, StringComparison.Ordinal));
            Assert.IsTrue(manager.GetString(key, en).StartsWith(LanguageSettings.UnknownResourcePrefix, StringComparison.Ordinal));
            Assert.IsTrue(manager.GetString(key, enUS).StartsWith(LanguageSettings.UnknownResourcePrefix, StringComparison.Ordinal));
            manager.ReleaseAllResources();
            Assert.IsTrue(manager.GetString(key, enUS).StartsWith(LanguageSettings.UnknownResourcePrefix, StringComparison.Ordinal));

            // If requested as derived with append, the new resource is merged into derived resources
            manager.AutoAppend = AutoAppendOptions.AddUnknownToInvariantCulture | AutoAppendOptions.AppendNeutralCultures;
            manager.ReleaseAllResources();
            Assert.IsTrue(manager.GetString(key, enUS).StartsWith(LanguageSettings.UntranslatedResourcePrefix + LanguageSettings.UnknownResourcePrefix, StringComparison.Ordinal));
            IExpandoResourceSet rsEn = manager.GetExpandoResourceSet(en, ResourceSetRetrieval.GetIfAlreadyLoaded, false);

            Assert.IsTrue(rsEn.ContainsResource(key));
            Assert.AreSame(rsEn, manager.GetResourceSet(enUS, false, false), "en should be proxied for en-US");
            manager.AutoAppend |= AutoAppendOptions.AppendSpecificCultures;
            Assert.IsTrue(manager.GetString(key, enUS).StartsWith(LanguageSettings.UntranslatedResourcePrefix + LanguageSettings.UnknownResourcePrefix, StringComparison.Ordinal));
            IExpandoResourceSet rsEnUs = manager.GetResourceSet(enUS, false, false) as IExpandoResourceSet;

            Assert.IsNotNull(rsEnUs);
            Assert.AreNotSame(rsEn, rsEnUs, "Due to merge a new resource set should have been created for en-US");
            Assert.IsTrue(rsEnUs.ContainsResource(key));

            // As object: null is added to invariant
            manager.ReleaseAllResources();
            Assert.IsNull(manager.GetObject(key, inv));
            manager.GetExpandoResourceSet(inv, ResourceSetRetrieval.GetIfAlreadyLoaded, false).ContainsResource(key);

            // but null is not merged even if the child resource sets are created
            Assert.IsNull(manager.GetObject(key, enUS));
            Assert.IsNotNull(manager.GetResourceSet(enUS, false, false));
            Assert.IsFalse(manager.GetExpandoResourceSet(enUS, ResourceSetRetrieval.GetIfAlreadyLoaded, false).ContainsResource(key));
            Assert.IsNotNull(manager.GetResourceSet(en, false, false));
            Assert.IsFalse(manager.GetExpandoResourceSet(en, ResourceSetRetrieval.GetIfAlreadyLoaded, false).ContainsResource(key));
            Assert.IsNotNull(manager.GetResourceSet(inv, false, false));
            Assert.IsTrue(manager.GetExpandoResourceSet(inv, ResourceSetRetrieval.GetIfAlreadyLoaded, false).ContainsResource(key));

            // a null object does not turn to string
            Assert.IsNull(manager.GetString(key, enUS));

            // changing back to compiled only sources disables appending invariant so exception will be thrown again
            manager.Source = ResourceManagerSources.CompiledOnly;
            Throws <MissingManifestResourceException>(() => manager.GetString(key, enUS));
        }