Exemple #1
0
        /// <summary>
        /// Adds the well-known <abbr title="document type definition">DTD</abbr> that is defined in XHTML 1.1
        /// to the <see cref="XmlPreloadedResolver"/> store.
        /// This DTD is already cached and embedded in the current assembly, so no network connections are required.
        /// </summary>
        /// <param name="resolver">The resolver to which to add the DTD for XHTML 1.1.</param>
        /// <param name="override">
        /// Whether to add the DTD and override the mappings for the URIs associated with XHTML 1.1 if they are already defined in the store.
        /// This can happen if the DTD for XHTML 1.1 is included by default in the <see cref="XmlPreloadedResolver"/> class
        /// in future or alternative implementations of the .NET Framework,
        /// or if the said DTD has already been added manually to the <paramref name="resolver"/> instance.
        /// </param>
        /// <returns>
        /// <see langword="true"/> if the DTD was added to the store and mapped to at least one of its URIs;
        /// <see langword="false"/> if both URIs were already defined and not overridden.
        /// </returns>
        /// <remarks>
        /// <para>
        /// The <see cref="XmlPreloadedResolver"/> class is preloaded by default with DTDs defined in XHTML 1.0 and RSS 0.91,
        /// but has not been updated to include XHTML 1.1 as of .NET Framework 4.6.1.
        /// Per the reference source for the <see href="http://referencesource.microsoft.com/#System.Xml/System/Xml/Resolvers/XmlPreloadedResolver.cs,33dd036cf1a84ad9">AddKnownDtd</see>
        /// private method of the <see cref="XmlPreloadedResolver"/> class, the default DTDs are mapped to both their public and their system identifiers.
        /// In the same vein, this method maps the DTD for XHTML 1.1 to its public identifier, <see cref="Xhtml11.DtdPublicId"/>,
        /// as well as to its system identifier, <see cref="Xhtml11.DtdSystemId"/>.
        /// </para>
        /// <para>
        /// The flattened version of the DTD for XHTML 1.1, which is embedded in the current assembly,
        /// is available at <see href="https://www.w3.org/TR/xhtml11/DTD/xhtml11-flat.dtd">xhtml11-flat.dtd</see>
        /// on the W3C website.
        /// </para>
        /// <list type="bullet">
        /// <listheader>References</listheader>
        /// <item><see href="https://en.wikipedia.org/wiki/XML_Catalog">XML Catalog</see>, <i>Wikipedia</i></item>
        /// <item><see href="http://stackoverflow.com/q/1645767/1149773">How do I resolve entities when loading into an XDocument?"</see>, <i>Stack Overflow</i></item>
        /// <item><see href="http://stackoverflow.com/q/3733255/1149773">How to speed up loading DTD through DOCTYPE</see>, <i>Stack Overflow</i></item>
        /// </list>
        /// </remarks>
        /// <example>
        /// <code>
        /// var xmlResolver = new XmlPreloadedResolver();
        /// xmlResolver.AddXhtml11();
        ///
        /// XmlReaderSettings settings = new XmlReaderSettings();
        /// settings.DtdProcessing = DtdProcessing.Parse;
        /// settings.XmlResolver = xmlResolver;
        ///
        /// XDocument document;
        /// using (var xmlReader = XmlReader.Create(input, settings))
        ///     document = XDocument.Load(xmlReader);
        /// </code>
        /// </example>
        public static void AddXhtml11(this XmlPreloadedResolver resolver, bool @override = false)
        {
            ArgumentValidate.NotNull(resolver, nameof(resolver));

            Add(resolver, new Uri(Xhtml11.DtdPublicId, UriKind.RelativeOrAbsolute), ManifestResources.Xhtml11FlatDtdBytes, @override);
            Add(resolver, new Uri(Xhtml11.DtdSystemId, UriKind.RelativeOrAbsolute), ManifestResources.Xhtml11FlatDtdBytes, @override);
        }
Exemple #2
0
        /// <summary>
        /// Reports the zero-based index of the first occurrence of the specified value in the sequence,
        /// using the specified equality comparer to compare it with the sequence's elements.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
        /// <param name="source">The sequence that contains the elements to search through.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="comparer">An <see cref="IEqualityComparer{T}"/> to compare values.</param>
        /// <returns>
        /// The zero-based index position of the first occurrence of an element in <paramref name="source"/>
        /// that is equal to <paramref name="value"/>, if found;
        /// or -1 if <paramref name="source"/> is empty or no match is found.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="source"/> or <paramref name="comparer"/> is <see langword="null"/>.
        /// </exception>
        public static int IndexOf <TSource>(this IEnumerable <TSource> source, TSource value, IEqualityComparer <TSource> comparer)
        {
            ArgumentValidate.NotNull(source, nameof(source));
            ArgumentValidate.NotNull(comparer, nameof(comparer));

            return(source.IndexOf(element => comparer.Equals(element, value)));
        }
        /// <summary>
        /// Transforms the asynchronous function delegate to deliver all exceptions asynchronously,
        /// through the returned <see cref="Task{TResult}"/>.
        /// This includes exceptions thrown from the synchronous part of the original asynchronous delegate,
        /// which would otherwise be thrown directly to the caller as soon as the delegate is invoked.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the delegate.</typeparam>
        /// <typeparam name="T4">The type of the fourth parameter of the delegate.</typeparam>
        /// <typeparam name="T5">The type of the fifth parameter of the delegate.</typeparam>
        /// <typeparam name="T6">The type of the sixth parameter of the delegate.</typeparam>
        /// <typeparam name="T7">The type of the seventh parameter of the delegate.</typeparam>
        /// <typeparam name="T8">The type of the eighth parameter of the delegate.</typeparam>
        /// <typeparam name="T9">The type of the ninth parameter of the delegate.</typeparam>
        /// <typeparam name="T10">The type of the tenth parameter of the delegate.</typeparam>
        /// <typeparam name="T11">The type of the eleventh parameter of the delegate.</typeparam>
        /// <typeparam name="T12">The type of the twelfth parameter of the delegate.</typeparam>
        /// <typeparam name="T13">The type of the thirteenth parameter of the delegate.</typeparam>
        /// <typeparam name="T14">The type of the fourteenth parameter of the delegate.</typeparam>
        /// <typeparam name="T15">The type of the fifteenth parameter of the delegate.</typeparam>
        /// <typeparam name="T16">The type of the sixteenth parameter of the delegate.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="asyncFunc">The asynchronous function delegate to be transformed.</param>
        /// <returns>The asynchronous function delegate encapsulating <paramref name="asyncFunc"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="asyncFunc"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="AsyncActionExtensions.DeliverAsync(Func{Task})"/> extension method.
        /// </remarks>
        public static Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Task <TResult> > DeliverAsync <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(this Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Task <TResult> > asyncFunc)
        {
            ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));

            return(async(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) =>
                   await asyncFunc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16).ConfigureAwait(false));
        }
        /// <summary>
        /// Verifies that an exception of type <see cref="AssertFailedException"/>
        /// is thrown during the execution of <paramref name="action"/>.
        /// The assertion fails if no uncaught exception is thrown,
        /// of if another type of exception is thrown.
        /// </summary>
        /// <param name="action">The action delegate that should throw the exception.</param>
        /// <param name="message">A message to display if the assertion fails. This message can be seen in the unit test results.</param>
        /// <returns>The exception that was thrown by <paramref name="action"/>.</returns>
        /// <example>
        /// This method is useful for writing unit tests to verify the implementation of methods in custom <c>…Assert</c> classes.
        /// For example, it is used for testing the <see cref="EnumerableAssert"/> class implemented in this library.
        /// <code>
        /// ExceptionAssert.ThrowsAssertFailed(() =&gt; Assert.Fail());
        /// ExceptionAssert.ThrowsAssertFailed(() =&gt; Assert.AreEqual(16, 32));
        /// </code>
        /// </example>
        public static AssertFailedException ThrowsAssertFailed(Action action, string message = null)
        {
            ArgumentValidate.NotNull(action, nameof(action));

            // Could call ThrowsInner instead to customize messages.
            return(Throws <AssertFailedException>(action, message));
        }
        /// <summary>
        /// Transforms the asynchronous function delegate to deliver all exceptions asynchronously,
        /// through the returned <see cref="Task{TResult}"/>.
        /// This includes exceptions thrown from the synchronous part of the original asynchronous delegate,
        /// which would otherwise be thrown directly to the caller as soon as the delegate is invoked.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="asyncFunc">The asynchronous function delegate to be transformed.</param>
        /// <returns>The asynchronous function delegate encapsulating <paramref name="asyncFunc"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="asyncFunc"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="AsyncActionExtensions.DeliverAsync(Func{Task})"/> extension method.
        /// </remarks>
        public static Func <T1, T2, Task <TResult> > DeliverAsync <T1, T2, TResult>(this Func <T1, T2, Task <TResult> > asyncFunc)
        {
            ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));

            return(async(T1 arg1, T2 arg2) =>
                   await asyncFunc(arg1, arg2).ConfigureAwait(false));
        }
Exemple #6
0
        /// <summary>
        /// Converts the specified hexadecimal string to an equivalent byte array of 8-bit unsigned integers.
        /// </summary>
        /// <param name="hex">The source hexadecimal string to convert.</param>
        /// <returns>A byte array of 8-bit unsigned integers that is equivalent to <paramref name="hex"/>.</returns>
        /// <remarks>
        /// <para>
        /// Both uppercase (<c>'A'</c> to <c>'F'</c>) and lowercase (<c>'a'</c> to <c>'f'</c>) hexadecimal characters are allowed.
        /// Since each hexadecimal character represents a nibble (four bits),
        /// a <i>pair</i> of hexadecimal characters is required to represent a byte (eight bits).
        /// For this reason, the source string must have an even number of characters;
        /// see <see href="http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa/24343727#comment2392703_311179">Stack Overflow comment</see>.
        /// </para>
        /// <para>
        /// This method implementation uses a <see href="https://en.wikipedia.org/wiki/Lookup_table">lookup table</see>.
        /// Refer to the remarks on the <see cref="ToHexadecimal"/> method for a performance discussion.
        /// Whilst <see cref="ToHexadecimal"/> performs lookups on a per-byte level,
        /// this methods does so on a per-nibble level.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="hex"/> is <see langword="null"/>.</exception>
        /// <exception cref="FormatException">
        /// The source string does not have an even number of characters. -or-
        /// The source string contains non-hexadecimal characters.
        /// </exception>
        public static byte[] FromHexadecimal(string hex)
        {
            ArgumentValidate.NotNull(hex, nameof(hex));
            if (hex.Length % 2 != 0)
            {
                throw new FormatException("The source string must have an even number of characters.");
            }

            byte[] result = new byte[hex.Length / 2];

            for (int i = 0; i < result.Length; i++)
            {
                char hiChar = hex[i * 2];
                char loChar = hex[i * 2 + 1];
                if (hiChar > 'f' || loChar > 'f')
                {
                    throw new FormatException("The source string contains non-hexadecimal characters.");
                }

                byte hi = hexValues[hiChar];
                byte lo = hexValues[loChar];
                if (hi == 255 || lo == 255)
                {
                    throw new FormatException("The source string contains non-hexadecimal characters.");
                }

                result[i] = (byte)((hi << 4) | lo);
            }

            return(result);
        }
Exemple #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="KeyComparer{TSource, TKey}"/> class,
        /// using the specified key extraction function and the specified or default
        /// sort-order comparer for extracted keys.
        /// </summary>
        /// <param name="keySelector">A function to extract the key from a source item.</param>
        /// <param name="innerComparer">
        /// The sort-order comparison operation to apply to the extracted keys.
        /// If the argument is omitted or specified as <see langword="null"/>,
        /// the <see cref="Comparer{T}.Default"/> comparer for type <typeparamref name="TKey"/> is used.
        /// </param>
        /// <exception cref="ArgumentNullException"><paramref name="keySelector"/> is <see langword="null"/>.</exception>
        protected internal KeyComparer(Func <TSource, TKey> keySelector, IComparer <TKey> innerComparer = null)
        {
            ArgumentValidate.NotNull(keySelector, nameof(keySelector));

            _keySelector   = keySelector;
            _innerComparer = innerComparer ?? Comparer <TKey> .Default;
        }
        /// <summary>
        /// Sets the culture used by the current thread to the <paramref name="culture"/> instance,
        /// and creates an <see cref="IDisposable"/> that restores the former culture when
        /// its <see cref="IDisposable.Dispose()"/> method is called.
        /// </summary>
        /// <param name="culture">The culture to set for the lifetime of this instance.</param>
        /// <exception cref="ArgumentNullException"><paramref name="culture"/> is <see langword="null"/>.</exception>
        public CultureSwapper(CultureInfo culture)
        {
            ArgumentValidate.NotNull(culture, nameof(culture));

            formerCulture = CultureInfo.CurrentCulture;
            CultureInfo.CurrentCulture = culture;
        }
        /// <summary>
        /// Transforms the asynchronous function delegate to deliver all exceptions asynchronously,
        /// through the returned <see cref="Task{TResult}"/>.
        /// This includes exceptions thrown from the synchronous part of the original asynchronous delegate,
        /// which would otherwise be thrown directly to the caller as soon as the delegate is invoked.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the delegate.</typeparam>
        /// <typeparam name="T4">The type of the fourth parameter of the delegate.</typeparam>
        /// <typeparam name="T5">The type of the fifth parameter of the delegate.</typeparam>
        /// <typeparam name="T6">The type of the sixth parameter of the delegate.</typeparam>
        /// <typeparam name="T7">The type of the seventh parameter of the delegate.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="asyncFunc">The asynchronous function delegate to be transformed.</param>
        /// <returns>The asynchronous function delegate encapsulating <paramref name="asyncFunc"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="asyncFunc"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="AsyncActionExtensions.DeliverAsync(Func{Task})"/> extension method.
        /// </remarks>
        public static Func <T1, T2, T3, T4, T5, T6, T7, Task <TResult> > DeliverAsync <T1, T2, T3, T4, T5, T6, T7, TResult>(this Func <T1, T2, T3, T4, T5, T6, T7, Task <TResult> > asyncFunc)
        {
            ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));

            return(async(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) =>
                   await asyncFunc(arg1, arg2, arg3, arg4, arg5, arg6, arg7).ConfigureAwait(false));
        }
Exemple #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EnumeratorPair{T}"/> class
        /// that iterates over the specified pair of sequences in sync,
        /// up to the end of the shorter sequence.
        /// </summary>
        /// <param name="sequence1">The first sequence over which to iterate.</param>
        /// <param name="sequence2">The second sequence over which to iterate.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sequence1"/> or <paramref name="sequence2"/> is <see langword="null"/>.
        /// </exception>
        public EnumeratorPair(IEnumerable <T> sequence1, IEnumerable <T> sequence2)
        {
            ArgumentValidate.NotNull(sequence1, nameof(sequence1));
            ArgumentValidate.NotNull(sequence2, nameof(sequence2));

            _enumerator1 = sequence1.GetEnumerator();
            _enumerator2 = sequence2.GetEnumerator();
        }
        /// <summary>
        /// Gets the User-Agent header of the client from which the incoming message was sent.
        /// </summary>
        /// <param name="context">The execution context for the current WCF service method.</param>
        /// <returns>The User-Agent header of the client.</returns>
        public static string GetUserAgent(this OperationContext context)
        {
            ArgumentValidate.NotNull(context, nameof(context));

            var httpRequest = context.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

            return(httpRequest.Headers[HttpRequestHeader.UserAgent]);
        }
        /// <summary>
        /// Gets the IP address of the client from which the incoming message was sent.
        /// </summary>
        /// <param name="context">The execution context for the current WCF service method.</param>
        /// <returns>The IP address of the client.</returns>
        /// <remarks>
        /// <list type="bullet">
        /// <listheader>References</listheader>
        /// <item><see href="http://stackoverflow.com/a/93437/1149773">Obtaining client IP address in WCF</see>, <i>Stack Overflow</i></item>
        /// </list>
        /// </remarks>
        public static string GetUserHostAddress(this OperationContext context)
        {
            ArgumentValidate.NotNull(context, nameof(context));

            var remoteEndpoint = context.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;

            return(remoteEndpoint.Address);
        }
        /// <summary>
        /// Returns a value indicating whether the specified substring occurs within the source string,
        /// using the specified string comparison for the search.
        /// </summary>
        /// <param name="source">The source string in which to search.</param>
        /// <param name="value">The string to seek.</param>
        /// <param name="comparisonType">One of the enumeration values that specifies the rules for the search.</param>
        /// <returns>
        /// <see langword="true"/> if the <paramref name="value"/> parameter occurs within the <paramref name="source"/> string,
        /// or if <paramref name="value"/> is the empty string (<c>""</c>);
        /// otherwise, <see langword="false"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="value"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="comparisonType"/> is not a valid <see cref="StringComparison"/> value.</exception>
        /// <remarks>
        /// The built-in <see cref="string.Contains(string)"/> method performs an ordinal (case-sensitive and culture-insensitive) comparison.
        /// This extension method allows the comparison type to be specified.
        /// </remarks>
        public static bool Contains(this string source, string value, StringComparison comparisonType)
        {
            ArgumentValidate.NotNull(source, nameof(source));
            ArgumentValidate.NotNull(value, nameof(value));
            ArgumentValidate.EnumDefined(comparisonType, nameof(comparisonType));

            return(source.IndexOf(value, comparisonType) >= 0);
        }
        /// <summary>
        /// Reports the zero-based index and length of the first occurrence of the specified substring in the source string.
        /// </summary>
        /// <param name="source">The source string in which to search.</param>
        /// <param name="substring">The substring to seek.</param>
        /// <param name="comparisonType">One of the enumeration values that specifies the rules for the search.</param>
        /// <param name="matchIndex">
        /// When this method returns, contains the zero-based starting character position of the match, if found;
        /// or -1 if no match is found.
        /// If <paramref name="substring"/> is the empty string (<c>""</c>), the value will be 0.
        /// </param>
        /// <param name="matchLength">
        /// When this method returns, contains the length (in characters) of the match, if found;
        /// or -1 if no match is found.
        /// If <paramref name="substring"/> is the empty string (<c>""</c>), the value will be 0.
        /// </param>
        /// <remarks>
        /// Refer to the remarks on the <see cref="Find(string, string, int, int, StringComparison, out int, out int)"/> overload.
        /// </remarks>
        public static void Find(this string source, string substring, StringComparison comparisonType, out int matchIndex, out int matchLength)
        {
            ArgumentValidate.NotNull(source, nameof(source));
            ArgumentValidate.NotNull(substring, nameof(substring));
            ArgumentValidate.EnumDefined(comparisonType, nameof(comparisonType));

            FindInner(source, substring, 0, source.Length, comparisonType, out matchIndex, out matchLength);
        }
        /// <summary>
        /// Reports the zero-based index and length of the first occurrence of the specified substring in the source string.
        /// </summary>
        /// <param name="source">The source string in which to search.</param>
        /// <param name="searchValue">The substring to seek.</param>
        /// <param name="comparisonType">One of the enumeration values that specifies the rules for the search.</param>
        /// <param name="matchIndex">
        /// When this method returns, contains the zero-based starting character position of the match, if found;
        /// or -1 if no match is found.
        /// If <paramref name="searchValue"/> is the empty string (<c>""</c>), the value will be 0.
        /// </param>
        /// <param name="matchLength">
        /// When this method returns, contains the length (in characters) of the match, if found;
        /// or -1 if no match is found.
        /// If <paramref name="searchValue"/> is the empty string (<c>""</c>), the value will be 0.
        /// </param>
        /// <returns>
        /// <see langword="true"/> if a match for <paramref name="searchValue"/> is found in the source string;
        /// otherwise, <see langword="false"/>.
        /// </returns>
        /// <remarks>
        /// Refer to the remarks on the
        /// <see cref="Find(string, string, int, int, StringComparison, out int, out int)"/> overload.
        /// </remarks>
        public static bool Find(this string source, string searchValue, StringComparison comparisonType, out int matchIndex, out int matchLength)
        {
            ArgumentValidate.NotNull(source, nameof(source));
            ArgumentValidate.NotNull(searchValue, nameof(searchValue));
            ArgumentValidate.EnumDefined(comparisonType, nameof(comparisonType));

            return(FindInner(source, searchValue, 0, source.Length, comparisonType, out matchIndex, out matchLength));
        }
        /// <summary>
        /// Creates or overwrites a file in the specified path.
        /// </summary>
        /// <param name="path">The path and name of the empty file to create.</param>
        /// <remarks>
        /// <list type="bullet">
        /// <listheader>References</listheader>
        /// <item><see href="http://stackoverflow.com/q/802541/1149773">Creating an empty file in C#</see>, <i>Stack Overflow</i></item>
        /// </list>
        /// </remarks>
        public static void CreateEmpty(string path)
        {
            ArgumentValidate.NotNull(path, nameof(path));

            using (File.Create(path))
            {
                // Do nothing; just need "using" statement to dispose the file stream.
            }
        }
        /// <summary>
        /// Verifies that the specified sequence is empty.
        /// The assertion fails if the sequence contains any elements.
        /// </summary>
        /// <typeparam name="T">The type of the elements of <paramref name="sequence"/>.</typeparam>
        /// <param name="sequence">The sequence that should be empty.</param>
        /// <param name="message">A message to display if the assertion fails. This message can be seen in the unit test results.</param>
        public static void IsEmpty <T>(IEnumerable <T> sequence, string message = "")
        {
            ArgumentValidate.NotNull(sequence, nameof(sequence));

            if (sequence.Any())
            {
                throw new AssertFailedException($"The sequence was expected to be empty, but actually contains {sequence.Count()} element(s). {message}");
            }
        }
        /// <summary>
        /// Verifies that an exception (of any type) is thrown during the asynchronous execution of <paramref name="asyncFunc"/>.
        /// The assertion fails if no uncaught exception is thrown.
        /// </summary>
        /// <param name="asyncFunc">The asynchronous delegate that should throw the exception.</param>
        /// <param name="message">A message to display if the assertion fails. This message can be seen in the unit test results.</param>
        /// <returns>
        /// A task that represents the asynchronous operation.
        /// The task result contains the exception that was thrown by <paramref name="asyncFunc"/>.
        /// </returns>
        /// <remarks>
        /// Refer to the remarks on the <see cref="ThrowsAsync{TException}(Func{Task}, string)"/> overload.
        /// </remarks>
        public static Task <Exception> ThrowsAsync(Func <Task> asyncFunc, string message = null)
        {
            ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));

            return(ThrowsAsyncInner <Exception>(asyncFunc,
                                                $"Expected exception, but none was thrown. {message}",
                                                t => $"Expected exception, but \"{t.Name}\" was thrown instead. {message}"));
            // Message for wrong type should never actually be needed.
        }
        /// <summary>
        /// Verifies that an exception (of any type) is thrown during the execution of <paramref name="action"/>.
        /// The assertion fails if no uncaught exception is thrown.
        /// </summary>
        /// <param name="action">The action delegate that should throw the exception.</param>
        /// <param name="message">A message to display if the assertion fails. This message can be seen in the unit test results.</param>
        /// <returns>The exception that was thrown by <paramref name="action"/>.</returns>
        /// <remarks>
        /// Refer to the remarks on the <see cref="Throws{TException}(Action, string)"/> overload.
        /// </remarks>
        public static Exception Throws(Action action, string message = null)
        {
            ArgumentValidate.NotNull(action, nameof(action));

            var asyncFunc = action.WrapAsync();
            var task      = ThrowsAsync(asyncFunc, message);

            return(task.GetResult());   // task is always completed; returns immediately
        }
        /// <summary>
        /// Executes the specified asynchronous function delegate using the disposable resource,
        /// then disposes of the said resource by calling its <see cref="IDisposable.Dispose()"/> method.
        /// </summary>
        /// <typeparam name="TDisposable">The type of the disposable resource to use.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the asynchronous function delegate.</typeparam>
        /// <param name="disposable">The disposable resource to use.</param>
        /// <param name="strategy">
        /// The strategy for propagating or swallowing exceptions thrown by the <see cref="IDisposable.Dispose"/> method.
        /// </param>
        /// <param name="asyncFunc">The asynchronous function delegate to execute using the disposable resource.</param>
        /// <returns>
        /// A task that represents the asynchronous operation.
        /// The task result contains the return value of the asynchronous function delegate.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="disposable"/> or <paramref name="asyncFunc"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="Using{TDisposable}(TDisposable, DisposeExceptionStrategy, Action{TDisposable})"/> overload.
        /// </remarks>
        public static Task <TResult> UsingAsync <TDisposable, TResult>(this TDisposable disposable, DisposeExceptionStrategy strategy, Func <TDisposable, Task <TResult> > asyncFunc)
            where TDisposable : IDisposable
        {
            ArgumentValidate.NotNull(disposable, nameof(disposable));
            ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));
            ArgumentValidate.EnumDefined(strategy, nameof(strategy));

            return(disposable.UsingAsyncInner(strategy, asyncFunc));
        }
Exemple #21
0
        /// <summary>
        /// Creates and starts a new thread to execute the specified action delegate.
        /// </summary>
        /// <param name="action">The action delegate to execute in the thread.</param>
        /// <returns>The created thread.</returns>
        /// <remarks>
        /// <para>
        /// This method initializes a new thread through the <see cref="Thread(ThreadStart)"/>
        /// constructor and calls its <see cref="Thread.Start()"/> method.
        /// Its purpose is conceptually similar
        /// to the <see cref="TaskFactory.StartNew(Action)"/> method of the <see cref="TaskFactory"/> class,
        /// or the <see cref="Task.Run(Action)"/> method of the <see cref="Task"/> class,
        /// but operates at the level of threads rather than tasks.
        /// </para>
        /// <para>
        /// Be careful with captured variables in the closure of the <paramref name="action"/> delegate.
        /// In the example below, the loop counter <c>i</c> is captured by the lambda expression;
        /// its value is likely to have been incremented <i>before</i> being read by the new thread.
        /// Consequently, the same value might be output by multiple threads; in the worst case,
        /// all threads would output the final value "8".
        /// <code>
        /// var threads = new Thread[8];
        /// for (int i = 0; i &lt; threads.Length; i++)
        ///     threads[i] = ThreadUtility.StartNew(() =&gt; Console.WriteLine(i));
        /// for (int i = 0; i &lt; threads.Length; i++)
        ///     threads[i].Join();
        /// </code>
        /// This issue can be fixed by using the <see cref="StartNew{TParam}(TParam, Action{TParam})"/>
        /// parameterized overload instead, passing the loop counter as the parameter:
        /// <code>
        /// var threads = new Thread[8];
        /// for (int i = 0; i &lt; threads.Length; i++)
        ///     threads[i] = ThreadUtility.StartNew(i, x =&gt; Console.WriteLine(x));
        /// for (int i = 0; i &lt; threads.Length; i++)
        ///     threads[i].Join();
        /// </code>
        /// Alternatively, one could use LINQ and avoid the need of a loop counter altogether:
        /// <code>
        /// Enumerable.Range(0, 8)
        ///           .Select(i =&gt; ThreadUtility.StartNew(() =&gt; Console.WriteLine(i)))
        ///           .ToList()
        ///           .ForEach(thread =&gt; thread.Join());
        /// </code>
        /// </para>
        /// </remarks>
        public static Thread StartNew(Action action)
        {
            ArgumentValidate.NotNull(action, nameof(action));

            var thread = new Thread(new ThreadStart(action));

            thread.Start();
            return(thread);
        }
        /// <summary>
        /// Returns an array of bytes filled with random numbers.
        /// </summary>
        /// <param name="random">The <see cref="Random"/> instance to generate the random numbers.</param>
        /// <param name="length">The length of the array of bytes to fill.</param>
        /// <returns>The array of bytes containing random numbers.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="random"/> is <see langword="null"/>.</exception>
        public static byte[] NextBytes(this Random random, int length)
        {
            ArgumentValidate.NotNull(random, nameof(random));

            var buffer = new byte[length];

            random.NextBytes(buffer);
            return(buffer);
        }
        /// <summary>
        /// Verifies that an exception of type <typeparamref name="TException"/> (or derived therefrom)
        /// is thrown during the asynchronous execution of <paramref name="asyncAction"/>.
        /// The assertion fails if no uncaught exception is thrown,
        /// of if another type of exception is thrown.
        /// </summary>
        /// <typeparam name="TException">The type of the exception expected to be thrown.</typeparam>
        /// <param name="asyncAction">The asynchronous delegate that should throw the exception.</param>
        /// <param name="message">A message to display if the assertion fails. This message can be seen in the unit test results.</param>
        /// <returns>
        /// A task that represents the asynchronous operation.
        /// The task result contains the exception that was thrown by <paramref name="asyncAction"/>.
        /// </returns>
        /// <remarks>
        /// <para>
        /// This method extends the <see cref="Throws{TException}(Action, string)"/> overload to support asynchronous delegates.
        /// Refer to the remarks on the said overload for the general functionality of these methods.
        /// </para>
        /// <list type="bullet">
        /// <listheader>References</listheader>
        /// <item><see href="https://msdn.microsoft.com/en-us/magazine/dn818493.aspx#code-snippet-8">Async Programming : Unit Testing Asynchronous Code</see> by Stephen Cleary</item>
        /// </list>
        /// </remarks>
        /// <example>
        /// <code>
        /// var exception = await ExceptionAssert.ThrowsAsync&lt;ArgumentNullException&gt;(async () =>
        /// {
        ///     using (var stream = new MemoryStream())
        ///     {
        ///         var buffer = new byte[128];
        ///         await stream.ReadAsync(buffer, 0, 256).ConfigureAwait(false);
        ///     }
        /// });
        /// </code>
        /// </example>
        public static Task <TException> ThrowsAsync <TException>(Func <Task> asyncAction, string message = null)
            where TException : Exception
        {
            ArgumentValidate.NotNull(asyncAction, nameof(asyncAction));

            return(ThrowsAsyncInner <TException>(asyncAction,
                                                 $"Expected exception of type \"{typeof(TException).Name}\", but no exception was thrown. {message}",
                                                 t => $"Expected exception of type \"{typeof(TException).Name}\", but \"{t.Name}\" was thrown instead. {message}"));
        }
        /// <summary>
        /// Creates a sequence consisting of the specified elements.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of the sequence.</typeparam>
        /// <param name="elements">The elements from which to create the sequence.</param>
        /// <returns>A sequence that contains the items in <paramref name="elements"/>.</returns>
        /// <remarks>
        /// <see href="http://stackoverflow.com/a/1577868/1149773">Jon Skeet recommends</see> against returning a list or an array,
        /// since an unscrupulous consumer could cast it back and change its contents, breaking the expected immutable behavior
        /// for other consumers of the same sequence.
        /// </remarks>
        public static IEnumerable <TSource> Yield <TSource>(params TSource[] elements)
        {
            ArgumentValidate.NotNull(elements, nameof(elements));

            foreach (var element in elements)
            {
                yield return(element);
            }
        }
        /// <summary>
        /// Verifies that the specified sequence contains the specified number of elements.
        /// </summary>
        /// <typeparam name="T">The type of the elements of <paramref name="sequence"/>.</typeparam>
        /// <param name="count">The expected number of elements that the sequence should contain.</param>
        /// <param name="sequence">The sequence that should <paramref name="count"/> elements.</param>
        /// <param name="message">A message to display if the assertion fails. This message can be seen in the unit test results.</param>
        public static void HasCount <T>(int count, IEnumerable <T> sequence, string message = "")
        {
            ArgumentValidate.NotNull(sequence, nameof(sequence));

            if (sequence.Count() != count)
            {
                throw new AssertFailedException($"The sequence was expected to contain {count} element(s), but actually contains {sequence.Count()}. {message}");
            }
        }
Exemple #26
0
        /// <summary>
        /// Transforms the asynchronous function delegate to deliver all exceptions asynchronously,
        /// through the returned <see cref="Task{TResult}"/>.
        /// This includes exceptions thrown from the synchronous part of the original asynchronous delegate,
        /// which would otherwise be thrown directly to the caller as soon as the delegate is invoked.
        /// </summary>
        /// <typeparam name="T">The type of the parameter of the delegate.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="asyncFunc">The asynchronous function delegate to be transformed.</param>
        /// <returns>The asynchronous function delegate encapsulating <paramref name="asyncFunc"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="asyncFunc"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="AsyncActionExtensions.DeliverAsync(Func{Task})"/> extension method.
        /// </remarks>
        public static Func <T, Task <TResult> > DeliverAsync <T, TResult>(this Func <T, Task <TResult> > asyncFunc)
        {
            ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));

            return(async(T arg) =>
            {
                return await asyncFunc(arg).ConfigureAwait(false);
            });
        }
        /// <summary>
        /// Creates an asynchronous delegate that executes the specified function delegate synchronously
        /// and returns a task that has completed successfully with the said delegate's result
        /// (like through <see cref="Task.FromResult{TResult}(TResult)"/>).
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the delegate.</typeparam>
        /// <typeparam name="T4">The type of the fourth parameter of the delegate.</typeparam>
        /// <typeparam name="T5">The type of the fifth parameter of the delegate.</typeparam>
        /// <typeparam name="T6">The type of the sixth parameter of the delegate.</typeparam>
        /// <typeparam name="T7">The type of the seventh parameter of the delegate.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="func">The function delegate to be executed synchronously by the asynchronous delegate.</param>
        /// <returns>The asynchronous delegate encapsulating <paramref name="func"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="WrapAsync{TResult}(Func{TResult})"/> overload.
        /// </remarks>
        public static Func <T1, T2, T3, T4, T5, T6, T7, Task <TResult> > WrapAsync <T1, T2, T3, T4, T5, T6, T7, TResult>(this Func <T1, T2, T3, T4, T5, T6, T7, TResult> func)
        {
            ArgumentValidate.NotNull(func, nameof(func));

            return((T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) =>
            {
                var result = func(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
                return Task.FromResult(result);
            });
        }
Exemple #28
0
        /// <summary>
        /// Creates and starts a new thread to execute the specified action delegate,
        /// supplying the specified parameter value.
        /// </summary>
        /// <typeparam name="TParam">The type of the parameter to be supplied to the action delegate.</typeparam>
        /// <param name="parameter">The parameter to be supplied to the action delegate.</param>
        /// <param name="action">
        /// The action delegate to execute in the thread.
        /// When run, the delegate will be passed <paramref name="parameter"/> as an argument.
        /// </param>
        /// <returns>The created thread.</returns>
        /// <remarks>
        /// <para>
        /// This method initializes a new thread through the <see cref="Thread(ParameterizedThreadStart)"/>
        /// constructor and calls its <see cref="Thread.Start(object)"/> method,
        /// supplying <paramref name="parameter"/> as the argument.
        /// Its purpose is conceptually similar to the <see cref="TaskFactory.StartNew(Action{object}, object)"/> method
        /// of the <see cref="TaskFactory"/> class, but operates at the level of threads rather than tasks.
        /// Unlike the .NET Framework classes, this method uses generics to ensure compile-time type safety.
        /// </para>
        /// <para>
        /// Refer to the remarks on the <see cref="StartNew(Action)"/> overload regarding captured variables.
        /// </para>
        /// </remarks>
        public static Thread StartNew <TParam>(TParam parameter, Action <TParam> action)
        {
            ArgumentValidate.NotNull(action, nameof(action));

            Action <object> actionObj = (object obj) => action((TParam)obj);
            var             thread    = new Thread(new ParameterizedThreadStart(actionObj));

            thread.Start(parameter);
            return(thread);
        }
        /// <summary>
        /// Creates an asynchronous delegate that executes the specified function delegate synchronously
        /// and returns a task that has completed successfully with the said delegate's result
        /// (like through <see cref="Task.FromResult{TResult}(TResult)"/>).
        /// </summary>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="func">The function delegate to be executed synchronously by the asynchronous delegate.</param>
        /// <returns>The asynchronous delegate encapsulating <paramref name="func"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>
        /// This method does not immediately execute the <paramref name="func"/> delegate.
        /// Rather, <paramref name="func"/> is encapsulated within an asynchronous delegate,
        /// and will be executed when the latter is invoked.
        /// In the case of an unhandled exception thrown by <paramref name="func"/>,
        /// the exception is propagated to the caller of the asynchronous delegate.
        /// </para>
        /// <para>
        /// The asynchronous delegate created by this method is just a <see cref="Task{TResult}"/>-returning wrapper over the
        /// <paramref name="func"/> delegate. It <i>does not</i> queue the specified work to run on the thread pool.
        /// For such functionality, use the <see cref="Task.Run{TResult}(Func{TResult})"/> method of the <see cref="Task"/> class.
        /// </para>
        /// <para>
        /// The asynchronous delegate created by this method delivers exceptions synchronously.
        /// This means that, if <paramref name="func"/> throws an unhandled exception, it will be propagated directly to its caller,
        /// and not encapsulated in the returned <see cref="Task{TResult}"/> (making it <see cref="TaskStatus.Faulted"/>).
        /// To get exceptions delivered asynchronously through the returned <see cref="Task{TResult}"/>, use the
        /// <see cref="AsyncFuncExtensions.DeliverAsync{TResult}(Func{Task{TResult}})"/> extension method on the created delegate.
        /// </para>
        /// <para>
        /// This method is convenient when implementing a pair of method overloads for some delegate-based functionality,
        /// with one overload taking an <see cref="Func{TResult}"/> parameter, and the other an asynchronous
        /// <see cref="Func{T}"/> of <see cref="Task{TResult}"/>,
        /// such as is the case for <see cref="Task.Run{TResult}(Func{TResult})"/> and <see cref="Task.Run{TResult}(Func{Task{TResult}})"/>.
        /// The function overload can be implemented by calling this <see cref="WrapAsync{TResult}(Func{TResult})"/> method
        /// on the <see cref="Func{TResult}"/> argument to convert it to an asynchronous <see cref="Func{T}"/> of <see cref="Task{TResult}"/>
        /// delegate returning a completed task with the former delegate's result, and then passing the created delegate
        /// to the asynchronous overload.
        /// </para>
        /// </remarks>
        /// <example>
        /// <code>
        /// public static TResult DoSomething&lt;TResult&gt;(Func&lt;TResult&gt; func)
        /// {
        ///     ArgumentValidate.NotNull(func, nameof(func));
        ///
        ///     var asyncFunc = func.WrapAsync();
        ///     var task = DoSomething(asyncFunc);
        ///     return task.GetAwaiter().GetResult();   // task is always completed; returns immediately
        /// }
        ///
        /// public static async Task&lt;TResult&gt; DoSomething&lt;TResult&gt;(Func&lt;Task&lt;TResult&gt;&gt; asyncFunc)
        /// {
        ///     ArgumentValidate.NotNull(asyncFunc, nameof(asyncFunc));
        ///
        ///     // preprocessing
        ///
        ///     try
        ///     {
        ///         return await asyncFunc().ConfigureAwait(false);
        ///     }
        ///     finally
        ///     {
        ///         // postprocessing
        ///     }
        /// }
        /// </code>
        /// </example>
        public static Func <Task <TResult> > WrapAsync <TResult>(this Func <TResult> func)
        {
            ArgumentValidate.NotNull(func, nameof(func));

            return(() =>
            {
                var result = func();
                return Task.FromResult(result);
            });
        }
        /// <summary>
        /// Creates an asynchronous delegate that executes the specified function delegate synchronously
        /// and returns a task that has completed successfully with the said delegate's result
        /// (like through <see cref="Task.FromResult{TResult}(TResult)"/>).
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the delegate.</typeparam>
        /// <typeparam name="T4">The type of the fourth parameter of the delegate.</typeparam>
        /// <typeparam name="T5">The type of the fifth parameter of the delegate.</typeparam>
        /// <typeparam name="T6">The type of the sixth parameter of the delegate.</typeparam>
        /// <typeparam name="T7">The type of the seventh parameter of the delegate.</typeparam>
        /// <typeparam name="T8">The type of the eighth parameter of the delegate.</typeparam>
        /// <typeparam name="T9">The type of the ninth parameter of the delegate.</typeparam>
        /// <typeparam name="T10">The type of the tenth parameter of the delegate.</typeparam>
        /// <typeparam name="T11">The type of the eleventh parameter of the delegate.</typeparam>
        /// <typeparam name="T12">The type of the twelfth parameter of the delegate.</typeparam>
        /// <typeparam name="T13">The type of the thirteenth parameter of the delegate.</typeparam>
        /// <typeparam name="T14">The type of the fourteenth parameter of the delegate.</typeparam>
        /// <typeparam name="T15">The type of the fifteenth parameter of the delegate.</typeparam>
        /// <typeparam name="T16">The type of the sixteenth parameter of the delegate.</typeparam>
        /// <typeparam name="TResult">The type of the return value of the delegate.</typeparam>
        /// <param name="func">The function delegate to be executed synchronously by the asynchronous delegate.</param>
        /// <returns>The asynchronous delegate encapsulating <paramref name="func"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// Refer to the remarks on the <see cref="WrapAsync{TResult}(Func{TResult})"/> overload.
        /// </remarks>
        public static Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Task <TResult> > WrapAsync <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(this Func <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> func)
        {
            ArgumentValidate.NotNull(func, nameof(func));

            return((T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) =>
            {
                var result = func(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
                return Task.FromResult(result);
            });
        }