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; } }