示例#1
0
        static void Main(string[] args)
        {
            var callback = Runner.createConsoleReporter(100);
            var property = Property.Default.Callback(callback);

            //A simple example
            property
            .Add(Syntax.Prop.ForAll(Arb.Array(Arb.Int).NonNull, xs => xs.Reverse().Reverse().SequenceEqual(xs)))
            .Run("RevRev");

            property
            .Add(Syntax.Prop.ForAll(Arb.Array(Arb.Int).NonNull, xs => xs.Reverse().SequenceEqual(xs)))
            .Run("RevId");

            //--------Properties--------------
            property
            .Add(Syntax.Prop.ForAll(Arb.Array(Arb.Single).NonNull, xs => xs.Reverse().Reverse().SequenceEqual(xs)))
            .Run("RevRevFloat");

            //conditional properties
            property
            .Add(Syntax.Prop.ForAll(Arb.Int, Arb.Array(Arb.Int).NonNull, (x, xs) =>
                                    new Lazy <bool>(() => xs.Insert(x).IsOrdered())
                                    .When(xs.IsOrdered())))
            .Run("Insert");

            property
            .Add(Syntax.Prop.ForAll(Arb.Int, a =>
                                    new Lazy <bool>(() => 1 / a == 1 / a)
                                    .When(a != 0)))
            .Run("DivByZero");

            //counting trivial cases
            property
            .Add(Syntax.Prop.ForAll(Arb.Int, Arb.Array(Arb.Int).NonNull, (x, xs) =>
                                    new Lazy <bool>(() => xs.Insert(x).IsOrdered())
                                    .When(xs.IsOrdered())
                                    .Classify(xs.Count() == 0, "trivial")))
            .Run("InsertTrivial");

            //classifying test values
            property
            .Add(Syntax.Prop.ForAll(Arb.Int, Arb.Array(Arb.Int).NonNull, (x, xs) =>
                                    new Lazy <bool>(() => xs.Insert(x).IsOrdered())
                                    .When(xs.IsOrdered())
                                    .Classify(new int[] { x }.Concat(xs).IsOrdered(), "at-head")
                                    .Classify(xs.Concat(new int[] { x }).IsOrdered(), "at-tail")))
            .Run("InsertClassify");

            //collecting data values
            property
            .Add(Syntax.Prop.ForAll(Arb.Int, Arb.Array(Arb.Int).NonNull, (x, xs) =>
                                    new Lazy <bool>(() => xs.Insert(x).IsOrdered())
                                    .When(xs.IsOrdered())
                                    .Collect("length " + xs.Count().ToString())))
            .Run("InsertCollect");

            //combining observations
            property
            .Add(Syntax.Prop.ForAll(Arb.Int, Arb.Array(Arb.Int).NonNull, (x, xs) =>
                                    new Lazy <bool>(() => xs.Insert(x).IsOrdered())
                                    .When(xs.IsOrdered())
                                    .Classify(new int[] { x }.Concat(xs).IsOrdered(), "at-head")
                                    .Classify(xs.Concat(new int[] { x }).IsOrdered(), "at-tail")
                                    .Collect("length " + xs.Count().ToString())))
            .Run("InsertCombined");

            //---labelling sub properties-----
            //hmm. Cannot express result = m + n once this way.
            property
            .Add(Syntax.Prop.ForAll(Arb.Int, Arb.Int, (m, n) =>
                                    (m + n >= m).Label("result > #1") //maybe add overload with label to ForAll?
                                    .And(() => (m + n >= n).Label("result > #2"))
                                    .And(() => (m + n < m + n).Label("result not sum"))))
            .Run("ComplexProp");

            property
            .Add(Syntax.Prop.ForAll(Arb.Int, x =>
                                    false.Label("Always false")
                                    .And(() => Math.Abs(x) - x == 0))) //actually, And should start a new property, not just a new assertion...
            .Run("Label");

            //rest seem hard to express without real "And" and "Or" support

            //-------Test data generators-----------
            //can't be made generic, only in separate method?
            Func <int[], Gen <int> > chooseFromList = xs =>
                                                      Gen.Choose(StatisticsModule.UniformDiscrete(0, xs.Length - 1))
                                                      .Select(i => xs[i]);

            var chooseBool = Persimmon.Dried.Ext.Gen.OneOf(Gen.Constant(true), Gen.Constant(false));

            //no tuples in C# until BCL 4.0...can we do better now?
            var chooseBool2 = Persimmon.Dried.Ext.Gen.Frequency(
                Tuple.Create(2, Gen.Constant(true)),
                Tuple.Create(1, Gen.Constant(false)));

            //the size of test data : see matrix method

            //generating recursive data types: not so common in C#?

            var config = new Configuration {
                Callback = callback
            };

            // generating functions:
            Syntax.Prop.ForAll(Arb.Func(CoArb.Int, Arb.Int), Arb.Func(CoArb.Int, Arb.Int), Arb.ICollection(Arb.Int).NonNull,
                               (f, g, a) => {
                var l1 = a.Select(x => f(g(x)));
                var l2 = a.Select(g).Select(f);
                return(l1.SequenceEqual(l2));
            }).Run(config);

            //generators support select, selectmany and where
            var gen = Arb.Int.Gen
                      .Where(x => x > 5)
                      .SelectMany(x => Gen.Choose(StatisticsModule.UniformDiscrete(5, 10)
                                                  .Select(y => new { Fst = x, Snd = y })));

            Syntax.Prop.ForAll(MyLongArb, l => l + 1 > l)
            .Run(config);

            Syntax.Prop.ForAll(Arb.String, s => true)
            .Run(new Configuration {
                Name = "Configuration Demo", MaxSize = 500, Callback = config.Callback
            });

            Syntax.Prop.ForAll(Arb.IEnumerable(Arb.Int).NonNull, Arb.IEnumerable(Arb.Int).NonNull,
                               (a, b) => a.Except(b).Count() <= a.Count())
            .Run(config);

            Console.ReadKey();
        }