public void EnumerationTest()
        {
            const int count = 1000;
            Dictionary <string, int> dictionary = Enumerable.Range(0, count).ToDictionary(i => i.ToString(CultureInfo.InvariantCulture));
            var strDict = new StringKeyedDictionary <int>(dictionary);

            new PerformanceTest <int> {
                TestName = "Indexer access test", Iterations = count
            }
            .AddCase(() =>
            {
                int sum = 0;
                foreach (KeyValuePair <string, int> item in dictionary)
                {
                    sum += item.Value;
                }

                return(sum);
            }, "Dictionary foreach")
            .AddCase(() => dictionary.Sum(item => item.Value), "Dictionary LINQ")
            .AddCase(() =>
            {
                int sum = 0;
                foreach (KeyValuePair <string, int> item in strDict)
                {
                    sum += item.Value;
                }

                return(sum);
            }, "StringKeyedDictionary foreach")
            .AddCase(() => strDict.Sum(item => item.Value), "StringKeyedDictionary LINQ")
            .DoTest()
            .DumpResults(Console.Out);
        }
Пример #2
0
        public void SerializationTest(StringComparison comparison)
        {
            var dict = new StringKeyedDictionary <int>(StringSegmentComparer.FromComparison(comparison))
            {
                { "alpha", 1 },
                { "beta", 2 },
                { "gamma", 3 },
                { "delta", 4 },
                { "epsilon", 5 }
            };

            // By BinarySerializationFormatter
            StringKeyedDictionary <int> clone = dict.DeepClone();

            Assert.AreNotSame(dict, clone);
            Assert.AreEqual(dict.Count, clone.Count);
            CollectionAssert.AreEqual(dict, clone);

            // By BinaryFormatter
            var formatter = new BinaryFormatter();

            using var ms = new MemoryStream();
            formatter.Serialize(ms, dict);
            ms.Position = 0;
            clone       = (StringKeyedDictionary <int>)formatter.Deserialize(ms);
            CollectionAssert.AreEqual(dict, clone);
        }
Пример #3
0
        public void KeysValuesTest()
        {
            var dict = new StringKeyedDictionary <int>
            {
                { "alpha", 1 },
                { "beta", 2 },
                { "gamma", 3 },
                { "delta", 4 },
                { "epsilon", 5 }
            };

            ICollection <string> keys = dict.Keys;

            Assert.AreEqual(dict.Count, keys.Count);
            CollectionAssert.AreEqual(dict.Select(c => c.Key), dict.Keys);


            ICollection <int> values = dict.Values;

            Assert.AreEqual(dict.Count, values.Count);
            CollectionAssert.AreEqual(dict.Select(c => c.Value), dict.Values);

            Assert.IsTrue(dict.Remove("beta"));
            Assert.AreEqual(dict.Count, keys.Count);
            Assert.AreEqual(dict.Count, values.Count);
        }
        public void ShouldMapBetweenSameComplexTypeDictionaryImplementations()
        {
            var source = new StringKeyedDictionary <Address>
            {
                ["One"] = new Address {
                    Line1 = "1.1", Line2 = "1.2"
                },
                ["Two"] = new Address {
                    Line1 = "2.1", Line2 = "2.2"
                },
                ["Three"] = default(Address),
            };
            var result = Mapper.Map(source).ToANew <StringKeyedDictionary <Address> >();

            result.Count.ShouldBe(3);

            result.ShouldContainKey("One");
            result["One"].Line1.ShouldBe("1.1");
            result["One"].Line2.ShouldBe("1.2");

            result.ShouldContainKey("Two");
            result["Two"].Line1.ShouldBe("2.1");
            result["Two"].Line2.ShouldBe("2.2");

            result.ShouldContainKey("Three");
            result["Three"].ShouldBeNull();
        }
        public void ShouldMergeAComplexTypeArrayFromUntypedDictionaryImplementationEntries()
        {
            var source = new StringKeyedDictionary <object>
            {
                ["Value[0]"] = new CustomerViewModel {
                    Name = "Mr Pants"
                },
                ["Value[1]"] = new PersonViewModel {
                    Name = "Ms Blouse"
                }
            };
            var target = new PublicProperty <PersonViewModel[]>
            {
                Value = new PersonViewModel[]
                {
                    new CustomerViewModel {
                        Name = "Sir Trousers", Discount = 0.99
                    }
                }
            };
            var originalValue1 = target.Value.First();
            var result         = Mapper.Map(source).OnTo(target);

            result.Value.Length.ShouldBe(3);

            result.Value.First().ShouldBe(originalValue1);
            result.Value.Second().Name.ShouldBe("Mr Pants");
            result.Value.Third().Name.ShouldBe("Ms Blouse");
        }
        public void ShouldMapBetweenDictionaryImplementations()
        {
            var source = new StringKeyedDictionary <Product>
            {
                ["One"] = new Product {
                    ProductId = "One!", Price = 9.99
                },
                ["Two"] = new Product {
                    ProductId = "Two!", Price = 10.00
                }
            };
            var target = new StringKeyedDictionary <ProductDto>
            {
                ["One"] = new ProductDto {
                    ProductId = "One!", Price = 99.99m
                }
            };

            var result = Mapper.Map(source).OnTo(target);

            result.Count.ShouldBe(2);

            result["One"].ProductId.ShouldBe("One!");
            result["One"].Price.ShouldBe(9.99m);

            result["Two"].ProductId.ShouldBe("Two!");
            result["Two"].Price.ShouldBe(10.00m);
        }
        public void ShouldMapToAnIntMemberFromADictionaryImplementationTypedEntry()
        {
            var source = new StringKeyedDictionary <long> {
                ["Value"] = 999
            };
            var result = Mapper.Map(source).ToANew <PublicField <long> >();

            result.ShouldNotBeNull();
            result.Value.ShouldBe(999L);
        }
Пример #8
0
        public void ShouldOverwriteFromASimpleTypeDictionaryImplementation()
        {
            var source = new StringKeyedDictionary <string> {
                ["Value"] = "LaLaLa!"
            };
            var target = new PublicField <string> {
                Value = "DumDeeDum!"
            };
            var result = Mapper.Map(source).Over(target);

            result.Value.ShouldBe("LaLaLa!");
        }
        public void PopulateTest()
        {
            const int count   = 1_000_000;
            var       dict    = new Dictionary <string, int>(count);
            var       strDict = new StringKeyedDictionary <int>(count);

            new IteratorPerformanceTest {
                TestName = "Populate test", Iterations = count
            }
            .AddCase(i => dict[i.ToString(CultureInfo.InvariantCulture)] = i, "Dictionary")
            .AddCase(i => strDict[i.ToString(CultureInfo.InvariantCulture)] = i, "StringKeyedDictionary")
            .DoTest()
            .DumpResults(Console.Out);
        }
        public void ShouldMapBetweenSameDeclaredSimpleTypeIDictionaries()
        {
            IDictionary <string, string> source = new StringKeyedDictionary <string>
            {
                ["Hello"] = "Bonjour",
                ["Yes"]   = "Oui"
            };
            var result = Mapper.Map(source).ToANew <IDictionary <string, string> >();

            result.Count.ShouldBe(2);

            result.ShouldContainKey("Hello");
            result["Hello"].ShouldBe("Bonjour");

            result.ShouldContainKey("Yes");
            result["Yes"].ShouldBe("Oui");
        }
Пример #11
0
        public void ShouldOverwriteASimpleTypeArrayToADictionaryImplementation()
        {
            var source = new[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
            var target = new StringKeyedDictionary <string>
            {
                ["[0]"] = source.First().ToString(),
                ["[1]"] = source.Third().ToString(),
                ["[4]"] = Guid.NewGuid().ToString()
            };
            var preMapping4 = target["[4]"];
            var result      = Mapper.Map(source).Over(target);

            result.Count.ShouldBe(4);
            result["[0]"].ShouldBe(source.First().ToString());
            result["[1]"].ShouldBe(source.Second().ToString());
            result["[2]"].ShouldBe(source.Third().ToString());
            result["[4]"].ShouldBe(preMapping4);
        }
        public void ShouldMergeSimpleTypeCollectionFromSimpleTypeDictionaryImplementationEntries()
        {
            var source = new StringKeyedDictionary <int>
            {
                ["Blah"]     = 5,
                ["Value[0]"] = 20,
                ["Value[1]"] = 30
            };
            var target = new PublicField <ICollection <short?> >
            {
                Value = new List <short?> {
                    10, 20
                }
            };
            var result = Mapper.Map(source).OnTo(target);

            result.Value.ShouldNotContain((short?)5);
            result.Value.ShouldBe((short?)10, (short?)20, (short?)30);
        }
        public void ShouldMapFromASimpleTypeDictionaryImplementationToAnIDictionary()
        {
            var source = new StringKeyedDictionary <string>
            {
                ["One"]   = "One!",
                ["Two"]   = "Two!",
                ["Three"] = "Three!",
            };
            var result = Mapper.Map(source).ToANew <IDictionary <string, string> >();

            result.Count.ShouldBe(3);

            result.ShouldContainKey("One");
            result["One"].ShouldBe("One!");

            result.ShouldContainKey("Two");
            result["Two"].ShouldBe("Two!");

            result.ShouldContainKey("Three");
            result["Three"].ShouldBe("Three!");
        }
        public void AccessTest(StringComparison?comparison)
        {
            const int             count = 100_000;
            StringComparer        sc    = null;
            StringSegmentComparer ssc   = null;

            if (comparison != null)
            {
#if NETFRAMEWORK || NETSTANDARD2_0
                sc = comparison.Value switch
                {
                    StringComparison.Ordinal => StringComparer.Ordinal,
                    StringComparison.OrdinalIgnoreCase => StringComparer.OrdinalIgnoreCase,
                    StringComparison.InvariantCulture => StringComparer.InvariantCulture,
                    StringComparison.InvariantCultureIgnoreCase => StringComparer.InvariantCultureIgnoreCase,
                    _ => throw new ArgumentOutOfRangeException(nameof(comparison))
                };
#else
                sc = StringComparer.FromComparison(comparison.Value);
#endif
                ssc = StringSegmentComparer.FromComparison(comparison.Value);
            }

            Dictionary <string, int> dictionary = Enumerable.Range(0, count).ToDictionary(i => i.ToString(CultureInfo.InvariantCulture), sc);
            var strDict = new StringKeyedDictionary <int>(dictionary, ssc);

            new IteratorPerformanceTest <int> {
                TestName = "Indexer access test", Iterations = count
            }
            .AddCase(i => dictionary[i.ToString(CultureInfo.InvariantCulture)], "Dictionary read")
            .AddCase(i => strDict[i.ToString(CultureInfo.InvariantCulture)], "StringKeyedDictionary read (string)")
            .AddCase(i => strDict[i.ToString(CultureInfo.InvariantCulture).AsSegment()], "StringKeyedDictionary read (StringSegment)")
#if !(NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0)
            .AddCase(i => strDict[i.ToString(CultureInfo.InvariantCulture).AsSpan()], "StringKeyedDictionary read (ReadOnlySpan<char>)")
#endif
            .DoTest()
            .DumpResults(Console.Out);
        }
Пример #15
0
        /// <summary>
        /// Tries to convert the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object.
        /// In case of success the return value is <see langword="true"/>&#160;and parsed <see langword="enum"/>&#160;is returned in <paramref name="result"/> parameter.
        /// </summary>
        /// <param name="value">The <see cref="string">string</see> representation of the enumerated value or values to parse.</param>
        /// <param name="separator">In case of more values specifies the separator among the values. If <see langword="null"/>&#160;or is empty, then comma (<c>,</c>) separator is used.</param>
        /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case.</param>
        /// <param name="result">Returns the default value of <typeparamref name="TEnum"/>, if return value is <see langword="false"/>; otherwise, the parsed <see langword="enum"/>&#160;value.</param>
        /// <returns><see langword="false"/>&#160;if the <see cref="string">string</see> in <paramref name="value"/> parameter cannot be parsed as <typeparamref name="TEnum"/>; otherwise, <see langword="true"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
        public static bool TryParse(string value, string separator, bool ignoreCase, out TEnum result)
        {
            if (value == null)
            {
                Throw.ArgumentNullException(Argument.value);
            }

            // simple name match test (always case-sensitive)
            if (NameValuePairs.TryGetValue(value, out result))
            {
                return(true);
            }

            var s = new StringSegmentInternal(value);

            s.Trim();
            result = default(TEnum);
            if (s.Length == 0)
            {
                return(false);
            }

            // simple numeric value
            char c = s[0];

            if (((c >= '0' && c <= '9') || c == '-' || c == '+') && s.TryParseIntQuick(underlyingInfo.IsSigned, underlyingInfo.MaxValue, out ulong numericValue))
            {
                result = converter.ToEnum(numericValue);
                return(true);
            }

            // rest: flags enum or ignored case
            if (String.IsNullOrEmpty(separator))
            {
                separator = EnumExtensions.DefaultParseSeparator;
            }

            ulong acc = 0UL;
            StringKeyedDictionary <ulong> dict = ignoreCase ? NameRawValuePairsIgnoreCase : NameRawValuePairs;

            while (s.TryGetNextSegment(separator, out StringSegmentInternal token))
            {
                token.Trim();
                if (token.Length == 0)
                {
                    return(false);
                }

                // literal token found in dictionary
                if (dict.TryGetValue(token, out ulong tokens))
                {
                    acc |= tokens;
                    continue;
                }

                // checking if is numeric token
                c = token[0];
                if (((c >= '0' && c <= '9') || c == '-' || c == '+') && token.TryParseIntQuick(underlyingInfo.IsSigned, underlyingInfo.MaxValue, out numericValue))
                {
                    acc |= numericValue;
                    continue;
                }

                // none of above
                return(false);
            }

            result = converter.ToEnum(acc);
            return(true);
        }
        public void OverloadConflictTest()
        {
            var dObj  = new Dictionary <string, object>();
            var dConv = new Dictionary <string, IConvertible>();

#if !(NET35 || NET40)
            IReadOnlyDictionary <string, IConvertible> dConvRo = dConv;
            IReadOnlyDictionary <string, object>       dObjRo  = dObj;
#endif
            IDictionary <string, IConvertible> dConvRw = dConv;
            IDictionary <string, object>       dObjRw  = dObj;

            // the extensions
            Assert.IsNull(dConv.GetValueOrDefault(""));
            Assert.IsNull(dObj.GetValueOrDefault(""));
#if !(NET35 || NET40)
            Assert.IsNull(dConvRo.GetValueOrDefault(""));
            Assert.IsNull(dObjRo.GetValueOrDefault(""));
            Assert.AreEqual(0, dObjRo.GetValueOrDefault <int>(""));
#endif
            Assert.IsNull(dConvRw.GetValueOrDefault(""));
            Assert.IsNull(dObjRw.GetValueOrDefault(""));

            // actual value extensions (so the GetValueOrDefault methods can have the same behavior as the .NET Core/Standard methods)
            Assert.AreEqual(0, dObjRw.GetValueOrDefault <int>(""));
            Assert.AreEqual(1, dConv.GetActualValueOrDefault("", 1));
            Assert.AreEqual(1, dObj.GetActualValueOrDefault("", 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dConvRo.GetActualValueOrDefault("", 1));
#endif
            Assert.AreEqual(1, dConvRw.GetActualValueOrDefault("", 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dObjRo.GetActualValueOrDefault("", 1));
#endif
            Assert.AreEqual(1, dObjRw.GetActualValueOrDefault("", 1));


            var dictConv = new StringKeyedDictionary <IConvertible>();
            var dictObj  = new StringKeyedDictionary <object>();
#if !(NET35 || NET40)
            IStringKeyedReadOnlyDictionary <IConvertible> dictConvRo = dictConv;
            IStringKeyedReadOnlyDictionary <object>       dictObjRo  = dictObj;
#endif
            IStringKeyedDictionary <IConvertible> dictConvRw = dictConv;
            IStringKeyedDictionary <object>       dictObjRw  = dictObj;

            // As StringKeyedDictionary defines these methods as well, these are not the extensions
            Assert.IsNull(dictConv.GetValueOrDefault(""));
            Assert.IsNull(dictObj.GetValueOrDefault(""));
#if !(NET35 || NET40)
            Assert.IsNull(dictConvRo.GetValueOrDefault(""));
            Assert.IsNull(dictObjRo.GetValueOrDefault(""));
            Assert.AreEqual(0, dictObjRo.GetValueOrDefault <int>(""));
#endif
            Assert.IsNull(dictConvRw.GetValueOrDefault(""));
            Assert.IsNull(dictObjRw.GetValueOrDefault(""));
            Assert.AreEqual(0, dictObjRw.GetValueOrDefault <int>(""));

            // But the extensions work seamlessly as for normal dictionaries
            Assert.AreEqual(1, dictConv.GetActualValueOrDefault("", 1));
            Assert.AreEqual(1, dictObj.GetActualValueOrDefault("", 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dictConvRo.GetActualValueOrDefault("", 1));
#endif
            Assert.AreEqual(1, dictConvRw.GetActualValueOrDefault("", 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dictObjRo.GetActualValueOrDefault("", 1));
#endif
            Assert.AreEqual(1, dictObjRw.GetActualValueOrDefault("", 1));

            // As here no need to be compatible with library methods, hese GetValueOrDefault can work the same way as GetActualValueOrDefault
            Assert.AreEqual(1, dictConv.GetValueOrDefault("", 1));
            Assert.AreEqual(1, dictObj.GetValueOrDefault("", 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dictConvRo.GetValueOrDefault("", 1));
#endif
            Assert.AreEqual(1, dictConvRw.GetValueOrDefault("", 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dictObjRo.GetValueOrDefault("", 1));
#endif
            Assert.AreEqual(1, dictObjRw.GetValueOrDefault("", 1));

            // StringSegment overloads
            Assert.IsNull(dictConv.GetValueOrDefault("".AsSegment()));
            Assert.IsNull(dictObj.GetValueOrDefault("".AsSegment()));
#if !(NET35 || NET40)
            Assert.IsNull(dictConvRo.GetValueOrDefault("".AsSegment()));
            Assert.IsNull(dictObjRo.GetValueOrDefault("".AsSegment()));
            Assert.AreEqual(0, dictObjRo.GetValueOrDefault <int>("".AsSegment()));
#endif
            Assert.IsNull(dictConvRw.GetValueOrDefault("".AsSegment()));
            Assert.IsNull(dictObjRw.GetValueOrDefault("".AsSegment()));
            Assert.AreEqual(0, dictObjRw.GetValueOrDefault <int>("".AsSegment()));
            Assert.AreEqual(1, dictConv.GetValueOrDefault("".AsSegment(), 1));
            Assert.AreEqual(1, dictObj.GetValueOrDefault("".AsSegment(), 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dictConvRo.GetValueOrDefault("".AsSegment(), 1));
#endif
            Assert.AreEqual(1, dictConvRw.GetValueOrDefault("".AsSegment(), 1));
#if !(NET35 || NET40)
            Assert.AreEqual(1, dictObjRo.GetValueOrDefault("".AsSegment(), 1));
#endif
            Assert.AreEqual(1, dictObjRw.GetValueOrDefault("".AsSegment(), 1));

#if !(NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0)
            // Span overloads
            Assert.IsNull(dictConv.GetValueOrDefault("".AsSpan()));
            Assert.IsNull(dictObj.GetValueOrDefault("".AsSpan()));
            Assert.IsNull(dictConvRo.GetValueOrDefault("".AsSpan()));
            Assert.IsNull(dictObjRo.GetValueOrDefault("".AsSpan()));
            Assert.AreEqual(0, dictObjRo.GetValueOrDefault <int>("".AsSpan()));
            Assert.IsNull(dictConvRw.GetValueOrDefault("".AsSpan()));
            Assert.IsNull(dictObjRw.GetValueOrDefault("".AsSpan()));
            Assert.AreEqual(0, dictObjRw.GetValueOrDefault <int>("".AsSpan()));
            Assert.AreEqual(1, dictConv.GetValueOrDefault("".AsSpan(), 1));
            Assert.AreEqual(1, dictObj.GetValueOrDefault("".AsSpan(), 1));
            Assert.AreEqual(1, dictConvRo.GetValueOrDefault("".AsSpan(), 1));
            Assert.AreEqual(1, dictConvRw.GetValueOrDefault("".AsSpan(), 1));
            Assert.AreEqual(1, dictObjRo.GetValueOrDefault("".AsSpan(), 1));
            Assert.AreEqual(1, dictObjRw.GetValueOrDefault("".AsSpan(), 1));
#endif
        }