[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Internal / Randomizer.cs
1 // ***********************************************************************
2 // Copyright (c) 2013-2015 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Reflection;
33 using System.Text;
34
35 namespace NUnit.Framework.Internal
36 {
37     /// <summary>
38     /// Randomizer returns a set of random _values in a repeatable
39     /// way, to allow re-running of tests if necessary. It extends
40     /// the .NET Random class, providing random values for a much
41     /// wider range of types.
42     /// 
43     /// The class is used internally by the framework to generate 
44     /// test case data and is also exposed for use by users through 
45     /// the TestContext.Random property.
46     /// </summary>
47     /// <remarks>
48     /// For consistency with the underlying Random Type, methods 
49     /// returning a single value use the prefix "Next..." Those
50     /// without an argument return a non-negative value up to
51     /// the full positive range of the Type. Overloads are provided
52     /// for specifying a maximum or a range. Methods that return
53     /// arrays or strings use the prefix "Get..." to avoid 
54     /// confusion with the single-value methods.
55     /// </remarks>
56     public class Randomizer : Random
57     {
58         #region Static Members
59
60         // Static constructor initializes values
61         static Randomizer()
62         {
63             InitialSeed = new Random().Next();
64             Randomizers = new Dictionary<MemberInfo, Randomizer>();
65         }
66
67         // Static Random instance used exclusively for the generation
68         // of seed values for new Randomizers.
69         private static Random _seedGenerator;
70
71         /// <summary>
72         /// Initial seed used to create randomizers for this run
73         /// </summary>
74         public static int InitialSeed
75         {
76             get { return _initialSeed; }
77             set
78             {
79                 _initialSeed = value;
80                 // Setting or resetting the initial seed creates seed generator
81                 _seedGenerator = new Random(_initialSeed);
82             }
83         }
84         private static int _initialSeed;
85
86         // Lookup Dictionary used to find randomizers for each member
87         private static Dictionary<MemberInfo, Randomizer> Randomizers;
88
89         /// <summary>
90         /// Get a Randomizer for a particular member, returning
91         /// one that has already been created if it exists.
92         /// This ensures that the same _values are generated
93         /// each time the tests are reloaded.
94         /// </summary>
95         public static Randomizer GetRandomizer(MemberInfo member)
96         {
97             if (Randomizers.ContainsKey(member))
98                 return Randomizers[member];
99             else
100             {
101                 var r = CreateRandomizer();
102                 Randomizers[member] = r;
103                 return r;
104             }
105         }
106
107
108         /// <summary>
109         /// Get a randomizer for a particular parameter, returning
110         /// one that has already been created if it exists.
111         /// This ensures that the same values are generated
112         /// each time the tests are reloaded.
113         /// </summary>
114         public static Randomizer GetRandomizer(ParameterInfo parameter)
115         {
116             return GetRandomizer(parameter.Member);
117         }
118
119         /// <summary>
120         /// Create a new Randomizer using the next seed
121         /// available to ensure that each randomizer gives
122         /// a unique sequence of values.
123         /// </summary>
124         /// <returns></returns>
125         public static Randomizer CreateRandomizer()
126         {
127             return new Randomizer(_seedGenerator.Next());
128         }
129
130         #endregion
131
132         #region Constructors
133
134         /// <summary>
135         /// Default constructor
136         /// </summary>
137         public Randomizer() { }
138
139         /// <summary>
140         /// Construct based on seed value
141         /// </summary>
142         /// <param name="seed"></param>
143         public Randomizer(int seed) : base(seed) { }
144
145         #endregion
146
147         #region Ints
148
149         // NOTE: Next(), Next(int max) and Next(int min, int max) are
150         // inherited from Random.
151
152         #endregion
153
154         #region Unsigned Ints
155
156         /// <summary>
157         /// Returns a random unsigned int.
158         /// </summary>
159         //[CLSCompliant(false)]
160         public uint NextUInt()
161         {
162             return NextUInt(0u, uint.MaxValue);
163         }
164
165         /// <summary>
166         /// Returns a random unsigned int less than the specified maximum.
167         /// </summary>
168         //[CLSCompliant(false)]
169         public uint NextUInt(uint max)
170         {
171             return NextUInt(0u, max);
172         }
173
174         /// <summary>
175         /// Returns a random unsigned int within a specified range.
176         /// </summary>
177         //[CLSCompliant(false)]
178         public uint NextUInt(uint min, uint max)
179         {
180             Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max");
181
182             if (min == max)
183                 return min;
184
185             uint range = max - min;
186
187             // Avoid introduction of modulo bias
188             uint limit = uint.MaxValue - uint.MaxValue % range;
189             uint raw;
190             do
191             {
192                 raw = RawUInt();
193             }
194             while (raw > limit);
195             
196             return unchecked(raw % range + min);
197         }
198
199         #endregion
200
201         #region Shorts
202
203         /// <summary>
204         /// Returns a non-negative random short.
205         /// </summary>
206         public short NextShort()
207         {
208             return NextShort(0, short.MaxValue);
209         }
210
211         /// <summary>
212         /// Returns a non-negative random short less than the specified maximum.
213         /// </summary>
214         public short NextShort(short max)
215         {
216             return NextShort((short)0, max);
217         }
218
219         /// <summary>
220         /// Returns a non-negative random short within a specified range.
221         /// </summary>
222         public short NextShort(short min, short max)
223         {
224             return (short)Next(min, max);
225         }
226
227         #endregion
228
229         #region Unsigned Shorts
230
231         /// <summary>
232         /// Returns a random unsigned short.
233         /// </summary>
234         //[CLSCompliant(false)]
235         public ushort NextUShort()
236         {
237             return NextUShort((ushort)0, ushort.MaxValue);
238         }
239
240         /// <summary>
241         /// Returns a random unsigned short less than the specified maximum.
242         /// </summary>
243         //[CLSCompliant(false)]
244         public ushort NextUShort(ushort max)
245         {
246             return NextUShort((ushort)0, max);
247         }
248
249         /// <summary>
250         /// Returns a random unsigned short within a specified range.
251         /// </summary>
252         //[CLSCompliant(false)]
253         public ushort NextUShort(ushort min, ushort max)
254         {
255             return (ushort)Next(min, max);
256         }
257
258         #endregion
259
260         #region Longs
261
262         /// <summary>
263         /// Returns a random long.
264         /// </summary>
265         public long NextLong()
266         {
267             return NextLong(0L, long.MaxValue);
268         }
269
270         /// <summary>
271         /// Returns a random long less than the specified maximum.
272         /// </summary>
273         public long NextLong(long max)
274         {
275             return NextLong(0L, max);
276         }
277
278         /// <summary>
279         /// Returns a non-negative random long within a specified range.
280         /// </summary>
281         public long NextLong(long min, long max)
282         {
283             Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max");
284
285             if (min == max)
286                 return min;
287
288             ulong range = (ulong)(max - min);
289
290             // Avoid introduction of modulo bias
291             ulong limit = ulong.MaxValue - ulong.MaxValue % range;
292             ulong raw;
293             do
294             {
295                 raw = RawULong();
296             }
297             while (raw > limit);
298
299             return (long)(raw % range + (ulong)min);
300         }
301
302         #endregion
303
304         #region Unsigned Longs
305
306         /// <summary>
307         /// Returns a random ulong.
308         /// </summary>
309         //[CLSCompliant(false)]
310         public ulong NextULong()
311         {
312             return NextULong(0ul, ulong.MaxValue);
313         }
314
315         /// <summary>
316         /// Returns a random ulong less than the specified maximum.
317         /// </summary>
318         //[CLSCompliant(false)]
319         public ulong NextULong(ulong max)
320         {
321             return NextULong(0ul, max);
322         }
323
324         /// <summary>
325         /// Returns a non-negative random long within a specified range.
326         /// </summary>
327         //[CLSCompliant(false)]
328         public ulong NextULong(ulong min, ulong max)
329         {
330             Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max");
331
332             ulong range = max - min;
333
334             if (range == 0)
335                 return min;
336
337             // Avoid introduction of modulo bias
338             ulong limit = ulong.MaxValue - ulong.MaxValue % range;
339             ulong raw;
340             do
341             {
342                 raw = RawULong();
343             }
344             while (raw > limit);
345             
346             return unchecked(raw % range + min);
347         }
348
349         #endregion
350
351         #region Bytes
352
353         /// <summary>
354         /// Returns a random Byte
355         /// </summary>
356         public byte NextByte()
357         {
358             return NextByte((byte)0, Byte.MaxValue);
359         }
360
361         /// <summary>
362         /// Returns a random Byte less than the specified maximum.
363         /// </summary>
364         public byte NextByte(byte max)
365         {
366             return NextByte((byte)0, max);
367         }
368
369         /// <summary>
370         /// Returns a random Byte within a specified range
371         /// </summary>
372         public byte NextByte(byte min, byte max)
373         {
374             return (byte)Next(min, max);
375         }
376
377         #endregion
378
379         #region SBytes
380
381         /// <summary>
382         /// Returns a random SByte
383         /// </summary>
384         //[CLSCompliant(false)]
385         public sbyte NextSByte()
386         {
387             return NextSByte((sbyte)0, SByte.MaxValue);
388         }
389
390         /// <summary>
391         /// Returns a random sbyte less than the specified maximum.
392         /// </summary>
393         //[CLSCompliant(false)]
394         public sbyte NextSByte(sbyte max)
395         {
396             return NextSByte((sbyte)0, max);
397         }
398
399         /// <summary>
400         /// Returns a random sbyte within a specified range
401         /// </summary>
402         //[CLSCompliant(false)]
403         public sbyte NextSByte(sbyte min, sbyte max)
404         {
405             return (sbyte)Next(min, max);
406         }
407
408         #endregion
409
410         #region Bools
411
412         /// <summary>
413         /// Returns a random bool
414         /// </summary>
415         public bool NextBool()
416         {
417             return NextDouble() < 0.5;
418         }
419
420         /// <summary>
421         /// Returns a random bool based on the probablility a true result
422         /// </summary>
423         public bool NextBool(double probability)
424         {
425             Guard.ArgumentInRange(probability >= 0.0 && probability <= 1.0, "Probability must be from 0.0 to 1.0", "probability");
426
427             return NextDouble() < probability;
428         }
429
430         #endregion
431
432         #region Doubles
433
434         // NOTE: NextDouble() is inherited from Random.
435
436         /// <summary>
437         /// Returns a random double between 0.0 and the specified maximum.
438         /// </summary>
439         public double NextDouble(double max)
440         {
441             return NextDouble() * max;
442         }
443
444         /// <summary>
445         /// Returns a random double within a specified range.
446         /// </summary>
447         public double NextDouble(double min, double max)
448         {
449             Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max");
450
451             if (max == min)
452                 return min;
453
454             double range = max - min;
455             return NextDouble() * range + min;
456         }
457
458         #endregion
459
460         #region Floats
461
462         /// <summary>
463         /// Returns a random float.
464         /// </summary>
465         public float NextFloat()
466         {
467             return (float)NextDouble();
468         }
469
470         /// <summary>
471         /// Returns a random float between 0.0 and the specified maximum.
472         /// </summary>
473         public float NextFloat(float max)
474         {
475             return (float)NextDouble(max);
476         }
477
478         /// <summary>
479         /// Returns a random float within a specified range.
480         /// </summary>
481         public float NextFloat(float min, float max)
482         {
483             return (float)NextDouble(min, max);
484         }
485
486         #endregion
487
488         #region Enums
489
490         /// <summary>
491         /// Returns a random enum value of the specified Type as an object.
492         /// </summary>
493         public object NextEnum(Type type)
494         {
495             Array enums = TypeHelper.GetEnumValues(type);
496             return enums.GetValue(Next(0, enums.Length));
497         }
498
499         /// <summary>
500         /// Returns a random enum value of the specified Type.
501         /// </summary>
502         public T NextEnum<T>()
503         {
504             return (T)NextEnum(typeof(T));
505         }
506
507         #endregion
508         
509         #region String
510         
511         /// <summary>
512         /// Default characters for random functions.
513         /// </summary>
514         /// <remarks>Default characters are the English alphabet (uppercase &amp; lowercase), arabic numerals, and underscore</remarks>
515         public const string DefaultStringChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789_";
516
517         private const int DefaultStringLength = 25;
518                 
519         /// <summary>
520         /// Generate a random string based on the characters from the input string.
521         /// </summary>
522         /// <param name="outputLength">desired length of output string.</param>
523         /// <param name="allowedChars">string representing the set of characters from which to construct the resulting string</param>
524         /// <returns>A random string of arbitrary length</returns>
525         public string GetString(int outputLength, string allowedChars)
526         {
527
528             var sb = new StringBuilder(outputLength);
529
530             for (int i = 0; i < outputLength ; i++)
531             {
532                 sb.Append(allowedChars[Next(0,allowedChars.Length)]);
533             }
534         
535             return sb.ToString();
536         }
537
538         /// <summary>
539         /// Generate a random string based on the characters from the input string.
540         /// </summary>
541         /// <param name="outputLength">desired length of output string.</param>
542         /// <returns>A random string of arbitrary length</returns>
543         /// <remarks>Uses <see cref="DefaultStringChars">DefaultStringChars</see> as the input character set </remarks>
544         public string GetString(int outputLength)
545         {
546             return GetString(outputLength, DefaultStringChars);
547         }
548
549         /// <summary>
550         /// Generate a random string based on the characters from the input string.
551         /// </summary>
552         /// <returns>A random string of the default length</returns>
553         /// <remarks>Uses <see cref="DefaultStringChars">DefaultStringChars</see> as the input character set </remarks>
554         public string GetString()
555         {
556             return GetString(DefaultStringLength, DefaultStringChars);
557         }
558
559         #endregion
560
561         #region Decimal
562
563         // We treat decimal as an integral type for now.
564         // The scaling factor is always zero.
565
566         /// <summary>
567         /// Returns a random decimal.
568         /// </summary>
569         public decimal NextDecimal()
570         {
571             int low = Next(0, int.MaxValue);
572             int mid = Next(0, int.MaxValue);
573             int high = Next(0, int.MaxValue);
574             return new Decimal(low, mid, high, false, 0);
575         }
576
577         /// <summary>
578         /// Returns a random decimal between positive zero and the specified maximum.
579         /// </summary>
580         public decimal NextDecimal(decimal max)
581         {
582             return NextDecimal() % max;
583         }
584
585         /// <summary>
586         /// Returns a random decimal within a specified range, which is not
587         /// permitted to exceed decimal.MaxVal in the current implementation.
588         /// </summary>
589         /// <remarks>
590         /// A limitation of this implementation is that the range from min
591         /// to max must not exceed decimal.MaxVal.
592         /// </remarks>
593         public decimal NextDecimal(decimal min, decimal max)
594         {
595             Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max");
596
597             // Check that the range is not greater than MaxValue without 
598             // first calculating it, since this would cause overflow
599             Guard.ArgumentValid(max < 0M == min < 0M || min + decimal.MaxValue >= max,
600                 "Range too great for decimal data, use double range", "max");
601
602             if (min == max)
603                 return min;
604
605             decimal range = max - min;
606
607             // Avoid introduction of modulo bias
608             decimal limit = decimal.MaxValue - decimal.MaxValue % range;
609             decimal raw;
610             do
611             {
612                 raw = NextDecimal();
613             }
614             while (raw > limit);
615
616             return unchecked(raw % range + min);
617         }
618
619         #endregion
620
621         #region Helper Methods
622
623         private uint RawUInt()
624         {
625             var buffer = new byte[sizeof(uint)];
626             NextBytes(buffer);
627             return BitConverter.ToUInt32(buffer, 0);
628         }
629
630         private uint RawUShort()
631         {
632             var buffer = new byte[sizeof(uint)];
633             NextBytes(buffer);
634             return BitConverter.ToUInt32(buffer, 0);
635         }
636
637         private ulong RawULong()
638         {
639             var buffer = new byte[sizeof(ulong)];
640             NextBytes(buffer);
641             return BitConverter.ToUInt64(buffer, 0);
642         }
643
644         private long RawLong()
645         {
646             var buffer = new byte[sizeof(long)];
647             NextBytes(buffer);
648             return BitConverter.ToInt64(buffer, 0);
649         }
650
651         private decimal RawDecimal()
652         {
653             int low = Next(0, int.MaxValue);
654             int mid = Next(0, int.MaxValue);
655             int hi = Next(0, int.MaxValue);
656             bool isNegative = NextBool();
657             byte scale = NextByte(29);
658             return new Decimal(low, mid, hi, isNegative, scale);
659         }
660
661         #endregion
662     }
663 }