Пример #1
0
        public void SelectManyTests()
        {
            // Plan: make a series of lists of different lengths and transform them
            // semi-randomly, but do the same transformation on a regular list. Then
            // ensure that the VList came out the same as the plain List.
            //
            // Note: this test isn't included in FVListTests because the FVList.Smart
            // methods act in "reverse order" compared to the LINQ methods Select/Where/etc.
            // so the results wouldn't be the same between List<int> and FVList<int>.
            int    initialLength = 0, trial = -1;
            string subtest = "";
            int    same = 0, pattern = 0;

            try {
                for (initialLength = 0; initialLength < 100; initialLength++)
                {
                    trial = -1;
                    VList <int> vlist = VList <int> .Empty;
                    List <int>  list  = new List <int>();
                    for (int i = 0; i < initialLength; i++)
                    {
                        vlist.Add(i);
                        list.Add(i);
                    }

                    // First, ensure that if the list is not changed, the same list comes out
                    subtest = "unchanged";
                    Assert.AreEqual(vlist, vlist.SmartSelect(i => i));
                    Assert.IsTrue(vlist == vlist.SmartSelect(i => i));
                    Assert.AreEqual(vlist, vlist.SmartWhere(i => true));
                    Assert.IsTrue(vlist == vlist.SmartWhere(i => true));
                    Assert.AreEqual(vlist, vlist.SmartSelectMany(i => new[] { i }));
                    Assert.IsTrue(vlist == vlist.SmartSelectMany(i => new[] { i }));

                    for (trial = 0; trial < (initialLength.IsInRange(1, 10) ? 4 : 1); trial++)
                    {
                        // Number of items to keep the same at the beginning of the transform
                        same    = initialLength == 0 ? 0 : _r.Next(8) % initialLength;
                        pattern = _r.Next();
                        int             index  = 0;
                        Func <int, int> select = n => ++ index <= same ? n : n + 1000;
                        Func <int, bool> where = n => ++ index <= same * 2 || ((pattern >> (index & 31)) & 1) == 0;
                        Func <int, IList <int> > selectMany = n =>
                        {
                            var @out = new List <int>();
                            if (index < same)
                            {
                                @out.Add(n);
                            }
                            else
                            {
                                for (int i = 0; i < ((pattern >> (index & 15)) & 3); i++)
                                {
                                    @out.Add(index * 1000 + i);
                                }
                            }
                            index++;
                            return(@out);
                        };
                        Func <int, IEnumerable <int> > selectManyE = n => selectMany(n);
                        subtest = "SmartSelect";
                        var expectS = list.Select(select); index = 0;
                        var resultS = vlist.SmartSelect(select); index = 0;
                        ExpectList(resultS, expectS);
                        subtest = "SmartWhere";
                        var expectW = list.Where(where); index = 0;
                        var resultW = vlist.SmartWhere(where); index = 0;
                        ExpectList(resultW, expectW);
                        subtest = "SmartSelectMany";
                        var expectM = list.SelectMany(selectManyE); index = 0;
                        var resultM = vlist.SmartSelectMany(selectMany); index = 0;
                        ExpectList(resultM, expectM);
                    }
                }
            } catch (Exception e) {
                e.Data["subtest"]       = subtest;
                e.Data["initialLength"] = initialLength;
                e.Data["trial"]         = trial;
                e.Data["same"]          = same;
                e.Data["pattern"]       = pattern;
                throw;
            }
        }