<commit_before>// Copyright 2005-2010 Gallio Project - http://www.gallio.org/
// Portions Copyright 2000-2004 <NAME>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using Aga.Controls.Tree;
using Gallio.Icarus.Controllers.Interfaces;
using Gallio.Icarus.Events;
using Gallio.Icarus.Models;
using Gallio.Icarus.Models.TestTreeNodes;
using Gallio.Model;
using Gallio.Runner.Reports.Schema;
using Gallio.UI.DataBinding;
using SortOrder=Gallio.Icarus.Models.SortOrder;

namespace Gallio.Icarus.Controllers
{
    public class TestResultsController : ITestResultsController, Handles<RunStarted>, 
        Handles<TestSelectionChanged>, Handles<RunFinished>, Handles<ExploreStarted>, 
        Handles<TestStepFinished>
    {
        private readonly ITestTreeModel testTreeModel;

        private readonly Stopwatch stopwatch = new Stopwatch();
        private readonly List<ListViewItem> listViewItems = new List<ListViewItem>();
        private int firstItem;
        private int lastItem;
        private int index;
        private int sortColumn = -1;
        private SortOrder sortOrder;
        private IList<TestTreeNode> selectedTests = new List<TestTreeNode>();

        public Observable<int> ResultsCount { get; private set; }

        public Observable<TimeSpan> ElapsedTime { get; private set; }

        public TestResultsController(ITestTreeModel testTreeModel)
        {
            this.testTreeModel = testTreeModel;

            ResultsCount = new Observable<int>();
            ElapsedTime = new Observable<TimeSpan>();
        }

        private void CountResults()
        {
            // invalidate cache
            listViewItems.Clear();
            ResultsCount.Value = 0;

            int count = 0;
            WalkTree(ttn => count += CountResults(ttn));
            
            // notify that list has changed
            ResultsCount.Value = count;
            ElapsedTime.Value = stopwatch.Elapsed;
        }

        private void WalkTree(Action<TestTreeNode> action)
        {
            if (selectedTests.Count == 0 && testTreeModel.Root != null)
            {
                action(testTreeModel.Root);
            }
            else
            {
                // need to do this because poxy namespace nodes don't really exist!
                foreach (var node in selectedTests)
                {
                    action(node);
                }
            }
        }

        private static int CountResults(TestTreeNode node)
        {
            int count = 0;
            count += node.TestStepRuns.Count;

            foreach (Node n in node.Nodes)
                count += CountResults((TestTreeNode) n);

            return count;
        }

        private void Reset()
        {
            ResultsCount.Value = 0;
            listViewItems.Clear();
          
            stopwatch.Reset();
            ElapsedTime.Value = stopwatch.Elapsed;
        }

        public void CacheVirtualItems(int startIndex, int endIndex)
        {
            if (startIndex >= firstItem && endIndex <= firstItem + listViewItems.Count)
            {
                // If the newly requested cache is a subset of the old cache, 
                // no need to rebuild everything, so do nothing.
                return;
            }

            firstItem = startIndex;
            lastItem = endIndex;

            UpdateTestResults();
        }

        public ListViewItem RetrieveVirtualItem(int itemIndex)
        {
            try
            {
                // update cache, if necessary
                if (itemIndex < firstItem)
                {
                    firstItem = itemIndex;
                    UpdateTestResults();
                }
                else if (itemIndex >= firstItem + listViewItems.Count)
                {
                    lastItem = itemIndex;
                    UpdateTestResults();
                }

                if ((itemIndex - firstItem) >= listViewItems.Count)
                {
                    UpdateTestResults();
                }

                return listViewItems[itemIndex - firstItem];
            }
            catch
            {
                // this is bad, and should never happen :(
                return new ListViewItem();
            }
        }

        private void UpdateTestResults()
        {
            listViewItems.Clear();
            index = 0;

            WalkTree(ttn => UpdateTestResults(ttn, 0));
<commit_msg>Make sure empty ListViewItem has all necessary sub-items.<commit_after>// Copyright 2005-2010 Gallio Project - http://www.gallio.org/
// Portions Copyright 2000-2004 <NAME>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using Aga.Controls.Tree;
using Gallio.Icarus.Controllers.Interfaces;
using Gallio.Icarus.Events;
using Gallio.Icarus.Models;
using Gallio.Icarus.Models.TestTreeNodes;
using Gallio.Model;
using Gallio.Runner.Reports.Schema;
using Gallio.UI.DataBinding;
using SortOrder=Gallio.Icarus.Models.SortOrder;

namespace Gallio.Icarus.Controllers
{
    public class TestResultsController : ITestResultsController, Handles<RunStarted>, 
        Handles<TestSelectionChanged>, Handles<RunFinished>, Handles<ExploreStarted>, 
        Handles<TestStepFinished>
    {
        private readonly ITestTreeModel testTreeModel;

        private readonly Stopwatch stopwatch = new Stopwatch();
        private readonly List<ListViewItem> listViewItems = new List<ListViewItem>();
        private int firstItem;
        private int lastItem;
        private int index;
        private int sortColumn = -1;
        private SortOrder sortOrder;
        private IList<TestTreeNode> selectedTests = new List<TestTreeNode>();

        public Observable<int> ResultsCount { get; private set; }

        public Observable<TimeSpan> ElapsedTime { get; private set; }

        public TestResultsController(ITestTreeModel testTreeModel)
        {
            this.testTreeModel = testTreeModel;

            ResultsCount = new Observable<int>();
            ElapsedTime = new Observable<TimeSpan>();
        }

        private void CountResults()
        {
            // invalidate cache
            listViewItems.Clear();
            ResultsCount.Value = 0;

            int count = 0;
            WalkTree(ttn => count += CountResults(ttn));
            
            // notify that list has changed
            ResultsCount.Value = count;
            ElapsedTime.Value = stopwatch.Elapsed;
        }

        private void WalkTree(Action<TestTreeNode> action)
        {
            if (selectedTests.Count == 0 && testTreeModel.Root != null)
            {
                action(testTreeModel.Root);
            }
            else
            {
                // need to do this because poxy namespace nodes don't really exist!
                foreach (var node in selectedTests)
                {
                    action(node);
                }
            }
        }

        private static int CountResults(TestTreeNode node)
        {
            int count = 0;
            count += node.TestStepRuns.Count;

            foreach (Node n in node.Nodes)
                count += CountResults((TestTreeNode) n);

            return count;
        }

        private void Reset()
        {
            ResultsCount.Value = 0;
            listViewItems.Clear();
          
            stopwatch.Reset();
            ElapsedTime.Value = stopwatch.Elapsed;
        }

        public void CacheVirtualItems(int startIndex, int endIndex)
        {
            if (startIndex >= firstItem && endIndex <= firstItem + listViewItems.Count)
            {
                // If the newly requested cache is a subset of the old cache, 
                // no need to rebuild everything, so do nothing.
                return;
            }

            firstItem = startIndex;
            lastItem = endIndex;

            UpdateTestResults();
        }

        public ListViewItem RetrieveVirtualItem(int itemIndex)
        {
            try
            {
                // update cache, if necessary
                if (itemIndex < firstItem)
                {
                    firstItem = itemIndex;
                    UpdateTestResults();
                }
                else if (itemIndex >= firstItem + listViewItems.Count)
                {
                    lastItem = itemIndex;
                    UpdateTestResults();
                }

                if ((itemIndex - firstItem) >= listViewItems.Count)
                {
                    UpdateTestResults();
                }

                return listViewItems[itemIndex - firstItem];
            }
            catch
            {
                // this is bad, and should never happen :(
                return EmptyListViewItem();
            }
        }

        private static ListViewItem EmptyListViewItem()
        {
            var listViewItem = new ListViewItem("", -1);
            listViewItem.SubItems.AddRange(new[] { "", "", "", "", "" });
            return listViewItem;
        }

        private void UpdateTestResults()
        {
            listViewItems.Clear();
            index = 0;

            WalkTree(ttn => UpdateTestResults(ttn, 0));

{'fraction_non_alphanumeric': 0.08089930822444273, 'fraction_numerical': 0.005476556495003843, 'mean_word_length': 1.7113831727012243, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6745456', 'n_tokens_mistral': 2653, 'n_tokens_neox': 2491, 'n_words': 726}