< Summary

Information
Class: MyNet.Generator.DefaultRandomGenerator
Assembly: MyNet.Generator
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Generator/DefaultRandomGenerator.cs
Tag: 323_28699572109
Line coverage
93%
Covered lines: 98
Uncovered lines: 7
Coverable lines: 105
Total lines: 297
Line coverage: 93.3%
Branch coverage
77%
Covered branches: 51
Total branches: 66
Branch coverage: 77.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%22100%
Bool()100%11100%
Weighted(...)100%66100%
Bytes(...)100%22100%
Item(...)75%44100%
Shuffle(...)100%22100%
Subset(...)100%44100%
Date(...)100%44100%
Enum(...)83.33%66100%
Int(...)100%11100%
Even(...)100%44100%
Odd(...)100%44100%
Double(...)100%11100%
Decimal(...)100%11100%
Float(...)100%11100%
Byte(...)100%11100%
SByte(...)100%11100%
UInt(...)50%2280%
ULong(...)50%2280%
Long(...)50%2283.33%
Short(...)50%22100%
UShort(...)50%22100%
String(...)66.66%6687.5%
Char(...)50%22100%
Letter(...)50%22100%
Digit()100%11100%
Chars(...)75%4483.33%
ValidateExclusiveRange(...)50%2266.66%
ValidateInclusiveRange(...)50%2266.66%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Generator/DefaultRandomGenerator.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="DefaultRandomGenerator.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Generic;
 9using System.Linq;
 10using MyNet.Primitives.Helpers;
 11
 12namespace MyNet.Generator;
 13
 14/// <summary>
 15/// Current implementation of <see cref="IRandomGenerator"/>.
 16/// </summary>
 17public sealed class DefaultRandomGenerator(IRandomSource source) : IRandomGenerator
 18{
 1919    private readonly IRandomSource _source = source ?? throw new ArgumentNullException(nameof(source));
 20
 21    /// <inheritdoc />
 60922    public bool Bool() => Weighted(0.5f);
 23
 24    /// <inheritdoc />
 25    public bool Weighted(float probability)
 121526        => probability is < 0.0f or > 1.0f
 121527            ? throw new ArgumentOutOfRangeException(nameof(probability), probability, "Probability must be between 0.0 a
 121528            : _source.NextDouble() < probability;
 29
 30    /// <inheritdoc />
 31    public byte[] Bytes(int count)
 32    {
 633        if (count < 0)
 334            throw new ArgumentOutOfRangeException(nameof(count), count, "Count cannot be negative.");
 35
 336        var buffer = new byte[count];
 337        _source.NextBytes(buffer);
 338        return buffer;
 39    }
 40
 41    /// <inheritdoc />
 42    public T Item<T>(IReadOnlyCollection<T> list)
 43    {
 21644        ArgumentNullException.ThrowIfNull(list);
 45
 21646        var finalList = list as IReadOnlyList<T> ?? [.. list];
 21647        return finalList.Count == 0 ? throw new ArgumentException("The list cannot be empty.", nameof(list)) : finalList
 48    }
 49
 50    /// <inheritdoc />
 51    public IEnumerable<T> Shuffle<T>(IEnumerable<T> source)
 52    {
 3653        ArgumentNullException.ThrowIfNull(source);
 54
 3655        var buffer = source.ToList();
 56
 38457        for (var i = buffer.Count - 1; i > 0; i--)
 58        {
 15659            var j = _source.NextInt32(0, i + 1);
 15660            (buffer[i], buffer[j]) = (buffer[j], buffer[i]);
 61        }
 62
 3663        return buffer;
 64    }
 65
 66    /// <inheritdoc />
 67    public IReadOnlyList<T> Subset<T>(IReadOnlyCollection<T> list, int count)
 68    {
 3669        ArgumentNullException.ThrowIfNull(list);
 70
 3671        return count < 0 || count > list.Count
 3672            ? throw new ArgumentOutOfRangeException(nameof(count), count, $"Count must be between 0 and the list size ({
 3673            : [.. Shuffle(list).Take(count)];
 74    }
 75
 76    /// <inheritdoc />
 77    public DateTime Date(DateTime min, DateTime max)
 78    {
 37879        if (min > max)
 380            throw new ArgumentOutOfRangeException(nameof(min), "min must be less than or equal to max.");
 81
 37582        var range = max.Ticks - min.Ticks;
 37583        if (range == 0)
 384            return min;
 85
 37286        var offset = (long)(_source.NextDouble() * range);
 37287        return new(min.Ticks + offset, min.Kind);
 88    }
 89
 90    /// <inheritdoc />
 91    public T Enum<T>(params T[] exclude)
 92        where T : struct, Enum
 93    {
 210394        var values = System.Enum.GetValues<T>();
 95
 210396        if (exclude is { Length: > 0 })
 45397            values = [.. values.Where(x => !exclude.Contains(x))];
 98
 210399        return values.Length == 0 ? throw new ArgumentException($"All values of enum '{typeof(T).Name}' have been exclud
 100    }
 101
 102    /// <inheritdoc />
 103    public int Int(int minInclusive = int.MinValue, int maxExclusive = int.MaxValue)
 104    {
 303105        ValidateExclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 303106        return _source.NextInt32(minInclusive, maxExclusive);
 107    }
 108
 109    /// <inheritdoc />
 110    public int Even(int minInclusive = int.MinValue, int maxExclusive = int.MaxValue)
 111    {
 303112        ValidateExclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 113
 303114        var start = (minInclusive & 1) == 0 ? minInclusive : minInclusive + 1L;
 303115        var end = (long)maxExclusive - 1;
 116
 303117        if (start > end)
 3118            throw new ArgumentOutOfRangeException(nameof(maxExclusive), "The range does not contain any even number.");
 119
 300120        var count = checked((int)(((end - start) / 2) + 1));
 300121        var offset = _source.NextInt32(0, count);
 122
 300123        return checked((int)(start + (2L * offset)));
 124    }
 125
 126    /// <inheritdoc />
 127    public int Odd(int minInclusive = int.MinValue, int maxExclusive = int.MaxValue)
 128    {
 303129        ValidateExclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 130
 303131        var start = (minInclusive & 1) == 1 ? minInclusive : minInclusive + 1L;
 303132        var end = (long)maxExclusive - 1;
 133
 303134        if (start > end)
 3135            throw new ArgumentOutOfRangeException(nameof(maxExclusive), "The range does not contain any odd number.");
 136
 300137        var count = checked((int)(((end - start) / 2) + 1));
 300138        var offset = _source.NextInt32(0, count);
 139
 300140        return checked((int)(start + (2L * offset)));
 141    }
 142
 143    /// <inheritdoc />
 144    public double Double(double minInclusive = int.MinValue, double maxExclusive = int.MaxValue)
 145    {
 300146        ValidateExclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 300147        return (_source.NextDouble() * (maxExclusive - minInclusive)) + minInclusive;
 148    }
 149
 150    /// <inheritdoc />
 151    public decimal Decimal(decimal minInclusive = 0.0m, decimal maxExclusive = 1.0m)
 152    {
 606153        ValidateExclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 606154        return (Convert.ToDecimal(_source.NextDouble()) * (maxExclusive - minInclusive)) + minInclusive;
 155    }
 156
 157    /// <inheritdoc />
 158    public float Float(float minInclusive = 0.0f, float maxExclusive = 1.0f)
 159    {
 600160        ValidateExclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 600161        return (Convert.ToSingle(_source.NextDouble()) * (maxExclusive - minInclusive)) + minInclusive;
 162    }
 163
 164    /// <inheritdoc />
 165    public byte Byte(byte minInclusive = byte.MinValue, byte maxExclusive = byte.MaxValue)
 166    {
 60167        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 60168        return Convert.ToByte(_source.NextInt32(minInclusive, maxExclusive + 1));
 169    }
 170
 171    /// <inheritdoc />
 172    public sbyte SByte(sbyte minInclusive = sbyte.MinValue, sbyte maxExclusive = sbyte.MaxValue)
 173    {
 60174        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 60175        return Convert.ToSByte(_source.NextInt32(minInclusive, maxExclusive + 1));
 176    }
 177
 178    /// <inheritdoc />
 179    public uint UInt(uint minInclusive = uint.MinValue, uint maxExclusive = uint.MaxValue)
 180    {
 303181        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 303182        if (minInclusive == maxExclusive)
 0183            return minInclusive;
 184
 303185        var value = (_source.NextDouble() * ((double)maxExclusive - minInclusive + 1)) + minInclusive;
 303186        return (uint)Math.Floor(value);
 187    }
 188
 189    /// <inheritdoc />
 190    public ulong ULong(ulong minInclusive = ulong.MinValue, ulong maxExclusive = ulong.MaxValue)
 191    {
 300192        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 300193        if (minInclusive == maxExclusive)
 0194            return minInclusive;
 195
 300196        var value = (_source.NextDouble() * ((double)maxExclusive - minInclusive + 1)) + minInclusive;
 300197        return (ulong)Math.Floor(value);
 198    }
 199
 200    /// <inheritdoc />
 201    public long Long(long minInclusive = long.MinValue, long maxExclusive = long.MaxValue)
 202    {
 303203        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 303204        if (minInclusive == maxExclusive)
 0205            return minInclusive;
 206
 303207        var range = ((decimal)maxExclusive - minInclusive) + 1;
 303208        var value = ((decimal)_source.NextDouble() * range) + minInclusive;
 303209        return decimal.ToInt64(decimal.Floor(value));
 210    }
 211
 212    /// <inheritdoc />
 213    public short Short(short minInclusive = short.MinValue, short maxExclusive = short.MaxValue)
 214    {
 303215        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 303216        return minInclusive == maxExclusive ? minInclusive : Convert.ToInt16(_source.NextInt32(minInclusive, maxExclusiv
 217    }
 218
 219    /// <inheritdoc />
 220    public ushort UShort(ushort minInclusive = ushort.MinValue, ushort maxExclusive = ushort.MaxValue)
 221    {
 300222        ValidateInclusiveRange(minInclusive, maxExclusive, nameof(minInclusive), nameof(maxExclusive));
 300223        return minInclusive == maxExclusive ? minInclusive : Convert.ToUInt16(_source.NextInt32(minInclusive, maxExclusi
 224    }
 225
 226    /// <inheritdoc />
 227    public string String(int length, ReadOnlySpan<char> chars = default)
 228    {
 3229        if (length < 0)
 0230            throw new ArgumentOutOfRangeException(nameof(length), length, "Length cannot be negative.");
 231
 3232        if (chars.IsEmpty)
 3233            chars = CharHelper.Alphabet;
 234
 3235        var buffer = new char[length];
 236
 54237        for (var i = 0; i < length; i++)
 24238            buffer[i] = chars[_source.NextInt32(0, chars.Length)];
 239
 3240        return new(buffer);
 241    }
 242
 243    /// <inheritdoc />
 15244    public char Char(char minInclusive = char.MinValue, char maxExclusive = char.MaxValue) => minInclusive >= maxExclusi
 245
 246    /// <inheritdoc />
 150247    public char Letter(bool uppercase = true) => (char)((uppercase ? 'A' : 'a') + _source.NextInt32(0, 26));
 248
 249    /// <inheritdoc />
 150250    public char Digit() => (char)('0' + _source.NextInt32(0, 10));
 251
 252    /// <inheritdoc />
 253    public char[] Chars(char minInclusive = char.MinValue, char maxExclusive = char.MaxValue, int count = 5)
 254    {
 3255        if (count < 0)
 0256            throw new ArgumentOutOfRangeException(nameof(count), count, "Count cannot be negative.");
 257
 3258        var arr = new char[count];
 30259        for (var i = 0; i < count; i++)
 12260            arr[i] = Char(minInclusive, maxExclusive);
 261
 3262        return arr;
 263    }
 264
 265    /// <summary>
 266    /// Validates that min is less than max. Throws an ArgumentOutOfRangeException if the condition is not met.
 267    /// </summary>
 268    /// <param name="min">The minimum value.</param>
 269    /// <param name="max">The maximum value.</param>
 270    /// <param name="minName">The name of the minimum value parameter.</param>
 271    /// <param name="maxName">The name of the maximum value parameter.</param>
 272    /// <typeparam name="T">The type of the values being compared.</typeparam>
 273    /// <exception cref="ArgumentOutOfRangeException">Thrown if min is not less than max.</exception>
 274    private static void ValidateExclusiveRange<T>(T min, T max, string minName, string maxName)
 275        where T : IComparable<T>
 276    {
 2415277        if (min.CompareTo(max) >= 0)
 0278            throw new ArgumentOutOfRangeException(minName, $"{minName} must be less than {maxName}.");
 2415279    }
 280
 281    /// <summary>
 282    /// Validates that min is less than or equal to max. Throws an ArgumentOutOfRangeException if the condition is not m
 283    /// </summary>
 284    /// <param name="min">The minimum value.</param>
 285    /// <param name="max">The maximum value.</param>
 286    /// <param name="minName">The name of the minimum value parameter.</param>
 287    /// <param name="maxName">The name of the maximum value parameter.</param>
 288    /// <typeparam name="T">The type of the values being compared.</typeparam>
 289    /// <exception cref="ArgumentOutOfRangeException">Thrown if min is not less than or equal to max.</exception>
 290    private static void ValidateInclusiveRange<T>(T min, T max, string minName, string maxName)
 291        where T : IComparable<T>
 292    {
 1629293        if (min.CompareTo(max) > 0)
 0294            throw new ArgumentOutOfRangeException(minName, $"{minName} must be less than or equal to {maxName}.");
 1629295    }
 296}
 297