com.wallstop-studios.unity-helpers 2.0.0-rc07 → 2.0.0-rc08

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,14 +4,30 @@
4
4
  using System.Collections.Generic;
5
5
  using System.Linq;
6
6
  using System.Runtime.CompilerServices;
7
+ using Core.DataStructure.Adapters;
7
8
  using Core.Extension;
8
9
  using Core.Serialization;
9
10
  using NUnit.Framework;
10
11
  using UnityHelpers.Core.Random;
11
12
 
13
+ public enum TestValues
14
+ {
15
+ Value0,
16
+ Value1,
17
+ Value2,
18
+ Value3,
19
+ Value4,
20
+ Value5,
21
+ Value6,
22
+ Value7,
23
+ Value8,
24
+ Value9,
25
+ }
26
+
12
27
  public abstract class RandomTestBase
13
28
  {
14
29
  private const int NumGeneratorChecks = 1_000;
30
+ private const int NormalIterations = 1_000;
15
31
  private const int SampleCount = 12_750_000;
16
32
 
17
33
  private readonly int[] _samples = new int[1_000];
@@ -34,7 +50,10 @@
34
50
  [Parallelizable]
35
51
  public void Bool()
36
52
  {
37
- TestAndVerify(random => Convert.ToInt32(random.NextBool()), maxLength: 2);
53
+ TestAndVerify(
54
+ random => Math.Min(_samples.Length - 1, Convert.ToInt32(random.NextBool())),
55
+ maxLength: Math.Min(2, _samples.Length)
56
+ );
38
57
  }
39
58
 
40
59
  [Test]
@@ -44,6 +63,16 @@
44
63
  TestAndVerify(random => random.Next(0, _samples.Length));
45
64
  }
46
65
 
66
+ [Test]
67
+ [Parallelizable]
68
+ public void IntRaw()
69
+ {
70
+ int sampleLength = GetSampleLength();
71
+ TestAndVerify(random =>
72
+ (int)((1.0 * random.Next()) / (1.0 * int.MaxValue) * sampleLength)
73
+ );
74
+ }
75
+
47
76
  [Test]
48
77
  [Parallelizable]
49
78
  public void IntRange()
@@ -119,6 +148,17 @@
119
148
  );
120
149
  }
121
150
 
151
+ [Test]
152
+ [Parallelizable]
153
+ public void ShortRaw()
154
+ {
155
+ int sampleLength = GetSampleLength(short.MaxValue);
156
+ TestAndVerify(
157
+ random => (int)((1.0 * random.NextShort()) / (1.0 * short.MaxValue) * sampleLength),
158
+ maxLength: short.MaxValue
159
+ );
160
+ }
161
+
122
162
  [Test]
123
163
  [Parallelizable]
124
164
  public void ShortRange()
@@ -156,6 +196,17 @@
156
196
  );
157
197
  }
158
198
 
199
+ [Test]
200
+ [Parallelizable]
201
+ public void ByteRaw()
202
+ {
203
+ int sampleLength = GetSampleLength(byte.MaxValue);
204
+ TestAndVerify(
205
+ random => (int)((1.0 * random.NextByte()) / (1.0 * byte.MaxValue) * sampleLength),
206
+ maxLength: byte.MaxValue
207
+ );
208
+ }
209
+
159
210
  [Test]
160
211
  [Parallelizable]
161
212
  public void ByteRange()
@@ -292,6 +343,16 @@
292
343
  TestAndVerify(random => (int)random.NextLong(0, _samples.Length));
293
344
  }
294
345
 
346
+ [Test]
347
+ [Parallelizable]
348
+ public void LongRaw()
349
+ {
350
+ int sampleLength = GetSampleLength();
351
+ TestAndVerify(random =>
352
+ (int)(1.0 * random.NextLong() / (1.0 * long.MaxValue) * sampleLength)
353
+ );
354
+ }
355
+
295
356
  [Test]
296
357
  [Parallelizable]
297
358
  public void LongRange()
@@ -319,6 +380,16 @@
319
380
  TestAndVerify(random => (int)random.NextUlong(0, (ulong)_samples.Length));
320
381
  }
321
382
 
383
+ [Test]
384
+ [Parallelizable]
385
+ public void UlongRaw()
386
+ {
387
+ int sampleLength = GetSampleLength();
388
+ TestAndVerify(random =>
389
+ (int)(1.0 * random.NextUlong() / (1.0 * ulong.MaxValue) * sampleLength)
390
+ );
391
+ }
392
+
322
393
  [Test]
323
394
  [Parallelizable]
324
395
  public void UlongRange()
@@ -339,6 +410,78 @@
339
410
  );
340
411
  }
341
412
 
413
+ [Test]
414
+ [Parallelizable]
415
+ public void NextBytes()
416
+ {
417
+ IRandom random = NewRandom();
418
+ HashSet<byte> seen = new();
419
+ int total = 0;
420
+ for (int i = 0; i < NormalIterations; ++i)
421
+ {
422
+ int size = random.Next(1, 40);
423
+ total += size;
424
+ byte[] buffer = new byte[size];
425
+ random.NextBytes(buffer);
426
+ foreach (byte value in buffer)
427
+ {
428
+ seen.Add(value);
429
+ }
430
+ }
431
+
432
+ double seenTargetMin = Math.Min(total, byte.MaxValue) * 0.9;
433
+ double seenTargetMax = Math.Min(total, byte.MaxValue) * 1.1;
434
+ Assert.LessOrEqual(seenTargetMin, seen.Count);
435
+ Assert.GreaterOrEqual(seenTargetMax, seen.Count);
436
+ }
437
+
438
+ [Test]
439
+ [Parallelizable]
440
+ public void NextGaussian()
441
+ {
442
+ IRandom random = NewRandom();
443
+ List<double> values = new();
444
+ for (int i = 0; i < NormalIterations; ++i)
445
+ {
446
+ double value = random.NextGaussian();
447
+ values.Add(value);
448
+ }
449
+
450
+ Assert.IsTrue(CheckApproximateNormality(values));
451
+ }
452
+
453
+ [Test]
454
+ [Parallelizable]
455
+ public void NextGuid()
456
+ {
457
+ IRandom random = NewRandom();
458
+
459
+ HashSet<Guid> seen = new();
460
+ for (int i = 0; i < NormalIterations; ++i)
461
+ {
462
+ Guid value = random.NextGuid();
463
+ seen.Add(value);
464
+ }
465
+
466
+ Assert.LessOrEqual(NormalIterations * 0.9, seen.Count);
467
+ }
468
+
469
+ [Test]
470
+ [Parallelizable]
471
+ public void NextKGuid()
472
+ {
473
+ IRandom random = NewRandom();
474
+
475
+ HashSet<KGuid> seen = new();
476
+ for (int i = 0; i < NormalIterations; ++i)
477
+ {
478
+ KGuid value = random.NextKGuid();
479
+ seen.Add(value);
480
+ }
481
+
482
+ Assert.LessOrEqual(NormalIterations * 0.9, seen.Count);
483
+ }
484
+
342
485
  [Test]
343
486
  [Parallelizable]
344
487
  public void Copy()
@@ -388,11 +531,164 @@
388
531
  }
389
532
  }
390
533
 
391
- protected virtual double DeviationFor(string caller)
534
+ [Test]
535
+ [Parallelizable]
536
+ public void NextEnumerable()
537
+ {
538
+ IRandom random = NewRandom();
539
+ for (int i = 0; i < NormalIterations; ++i)
540
+ {
541
+ HashSet<TestValues> selected = Enum.GetValues(typeof(TestValues))
542
+ .OfType<TestValues>()
543
+ .Shuffled(random)
544
+ .Skip(3)
545
+ .ToHashSet();
546
+
547
+ TestValues value = random.NextOf(selected.Shuffled(random));
548
+ Assert.IsTrue(selected.Contains(value));
549
+ }
550
+ }
551
+
552
+ [Test]
553
+ [Parallelizable]
554
+ public void NextArray()
555
+ {
556
+ IRandom random = NewRandom();
557
+ for (int i = 0; i < NormalIterations; ++i)
558
+ {
559
+ TestValues[] values = Enum.GetValues(typeof(TestValues))
560
+ .OfType<TestValues>()
561
+ .Shuffled(random)
562
+ .Skip(3)
563
+ .ToArray();
564
+
565
+ TestValues value = random.NextOf(values);
566
+ Assert.IsTrue(values.Contains(value));
567
+ }
568
+ }
569
+
570
+ [Test]
571
+ [Parallelizable]
572
+ public void NextList()
573
+ {
574
+ IRandom random = NewRandom();
575
+ for (int i = 0; i < NormalIterations; ++i)
576
+ {
577
+ List<TestValues> values = Enum.GetValues(typeof(TestValues))
578
+ .OfType<TestValues>()
579
+ .Shuffled(random)
580
+ .Skip(3)
581
+ .ToList();
582
+
583
+ TestValues value = random.NextOf(values);
584
+ Assert.IsTrue(values.Contains(value));
585
+ }
586
+ }
587
+
588
+ [Test]
589
+ [Parallelizable]
590
+ public void NextHashSet()
591
+ {
592
+ IRandom random = NewRandom();
593
+ for (int i = 0; i < NormalIterations; ++i)
594
+ {
595
+ HashSet<TestValues> values = Enum.GetValues(typeof(TestValues))
596
+ .OfType<TestValues>()
597
+ .Shuffled(random)
598
+ .Skip(3)
599
+ .ToHashSet();
600
+
601
+ TestValues value = random.NextOf(values);
602
+ Assert.IsTrue(values.Contains(value));
603
+ }
604
+ }
605
+
606
+ [Test]
607
+ [Parallelizable]
608
+ public void NextLinkedList()
609
+ {
610
+ IRandom random = NewRandom();
611
+ for (int i = 0; i < NormalIterations; ++i)
612
+ {
613
+ LinkedList<TestValues> values = Enum.GetValues(typeof(TestValues))
614
+ .OfType<TestValues>()
615
+ .Shuffled(random)
616
+ .Skip(3)
617
+ .ToLinkedList();
618
+
619
+ TestValues value = random.NextOf(values);
620
+ Assert.IsTrue(values.Contains(value));
621
+ }
622
+ }
623
+
624
+ [Test]
625
+ [Parallelizable]
626
+ public void NextEnum()
627
+ {
628
+ IRandom random = NewRandom();
629
+ HashSet<TestValues> seenEnums = new();
630
+ for (int i = 0; i < NormalIterations; ++i)
631
+ {
632
+ TestValues value = random.NextEnum<TestValues>();
633
+ _ = seenEnums.Add(value);
634
+ }
635
+
636
+ Assert.AreEqual(Enum.GetValues(typeof(TestValues)).Length, seenEnums.Count);
637
+ }
638
+
639
+ [Test]
640
+ [Parallelizable]
641
+ public void NextNoiseMap()
642
+ {
643
+ IRandom random = NewRandom();
644
+ for (int i = 0; i < NormalIterations; ++i)
645
+ {
646
+ int width = random.Next(1, 75);
647
+ int height = random.Next(1, 75);
648
+ float[,] noise = random.NextNoiseMap(width, height);
649
+ Assert.IsNotNull(noise);
650
+ Assert.AreEqual(width * height, noise.Length);
651
+ foreach (float value in noise)
652
+ {
653
+ Assert.LessOrEqual(0f, value);
654
+ Assert.GreaterOrEqual(1.1f, value);
655
+ }
656
+ }
657
+ }
658
+
659
+ protected virtual double GetDeviationFor(string caller)
392
660
  {
393
661
  return 0.0625;
394
662
  }
395
663
 
664
+ private static bool CheckApproximateNormality(IEnumerable<double> data)
665
+ {
666
+ IReadOnlyList<double> input = data as IReadOnlyList<double> ?? data.ToArray();
667
+ int n = input.Count;
668
+ if (n < 3)
669
+ {
670
+ return true;
671
+ }
672
+
673
+ double mean = input.Average();
674
+ double variance = input.Sum(x => Math.Pow(x - mean, 2)) / n;
675
+ double stdDev = Math.Sqrt(variance);
676
+
677
+ double skewness = input.Sum(x => Math.Pow((x - mean) / stdDev, 3)) / n;
678
+ double kurtosis = input.Sum(x => Math.Pow((x - mean) / stdDev, 4)) / n - 3; // Excess kurtosis
679
+
680
+ // Thresholds can be defined based on empirical rules or domain-specific values
681
+ const double skewnessThreshold = 0.5;
682
+ const double kurtosisThreshold = 1.0;
683
+
684
+ return Math.Abs(skewness) < skewnessThreshold && Math.Abs(kurtosis) < kurtosisThreshold;
685
+ }
686
+
687
+ protected int GetSampleLength(int? sampleLength = null)
688
+ {
689
+ return Math.Min(_samples.Length, sampleLength ?? _samples.Length);
690
+ }
691
+
396
692
  private void TestAndVerify(
397
693
  Func<IRandom, int> sample,
398
694
  int? maxLength = null,
@@ -414,9 +710,9 @@
414
710
  }
415
711
  }
416
712
 
417
- sampleLength = Math.Min(sampleLength, maxLength ?? sampleLength);
713
+ sampleLength = GetSampleLength(maxLength);
418
714
  double average = SampleCount * 1.0 / sampleLength;
419
- double deviationAllowed = average * DeviationFor(caller);
715
+ double deviationAllowed = average * GetDeviationFor(caller);
420
716
  List<int> zeroCountIndexes = new();
421
717
  List<int> outsideRange = new();
422
718
  for (int i = 0; i < sampleLength; i++)
@@ -6,7 +6,7 @@
6
6
  {
7
7
  protected override IRandom NewRandom() => new SquirrelRandom();
8
8
 
9
- protected override double DeviationFor(string caller)
9
+ protected override double GetDeviationFor(string caller)
10
10
  {
11
11
  return 0.075;
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc07",
3
+ "version": "2.0.0-rc08",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},