diff --git a/src/TestCentric/testcentric.gui/Presenters/TestCentricPresenter.cs b/src/TestCentric/testcentric.gui/Presenters/TestCentricPresenter.cs index 566423e5..bb426877 100644 --- a/src/TestCentric/testcentric.gui/Presenters/TestCentricPresenter.cs +++ b/src/TestCentric/testcentric.gui/Presenters/TestCentricPresenter.cs @@ -987,7 +987,10 @@ private void RunFailedTests() { var test = entry.Value; if (!test.IsSuite && test.Outcome.Status == TestStatus.Failed) - failedTests.Add(test); + { + TestNode testNode = _model.GetTestById(test.Id); + failedTests.Add(testNode); + } } _model.RunTests(failedTests); diff --git a/src/TestModel/model/Filter/CategoryFilter.cs b/src/TestModel/model/Filter/CategoryFilter.cs index 52e2ee99..d0e18ae5 100644 --- a/src/TestModel/model/Filter/CategoryFilter.cs +++ b/src/TestModel/model/Filter/CategoryFilter.cs @@ -18,7 +18,7 @@ public class CategoryFilter : ITestFilter private List _condition = new List(); - internal CategoryFilter(ITestModel model) + public CategoryFilter(ITestModel model) { TestModel = model; } @@ -33,6 +33,8 @@ public IEnumerable Condition set { _condition = value.ToList(); } } + public bool IsActive => AllCategories.Except(_condition).Any(); + public IEnumerable AllCategories { get; private set; } public bool IsMatching(TestNode testNode) diff --git a/src/TestModel/model/Filter/ITestCentricTestFilter.cs b/src/TestModel/model/Filter/ITestCentricTestFilter.cs index fd635f2a..370b19b9 100644 --- a/src/TestModel/model/Filter/ITestCentricTestFilter.cs +++ b/src/TestModel/model/Filter/ITestCentricTestFilter.cs @@ -32,6 +32,11 @@ public interface ITestCentricTestFilter /// IEnumerable AllCategories { get; } + /// + /// Checks if any filter is active + /// + bool IsActive { get; } + /// /// Clear all actives filters and reset them to default /// diff --git a/src/TestModel/model/Filter/ITestFilter.cs b/src/TestModel/model/Filter/ITestFilter.cs index 98981036..454fdb04 100644 --- a/src/TestModel/model/Filter/ITestFilter.cs +++ b/src/TestModel/model/Filter/ITestFilter.cs @@ -36,5 +36,10 @@ internal interface ITestFilter /// Checks if the testNode matches the filter condition /// bool IsMatching(TestNode testNode); + + /// + /// Checks if the filter is active + /// + bool IsActive { get; } } } diff --git a/src/TestModel/model/Filter/OutcomeFilter.cs b/src/TestModel/model/Filter/OutcomeFilter.cs index b25fc46a..4a1a6f9a 100644 --- a/src/TestModel/model/Filter/OutcomeFilter.cs +++ b/src/TestModel/model/Filter/OutcomeFilter.cs @@ -18,7 +18,7 @@ public class OutcomeFilter : ITestFilter private List _condition = new List(); - internal OutcomeFilter(ITestModel model) + public OutcomeFilter(ITestModel model) { TestModel = model; } @@ -33,6 +33,8 @@ public IEnumerable Condition set { _condition = value.ToList(); } } + public bool IsActive => _condition.Any(); + public bool IsMatching(TestNode testNode) { // All kind of outcomes should be displayed (no outcome filtering) diff --git a/src/TestModel/model/Filter/TestCentricTestFilter.cs b/src/TestModel/model/Filter/TestCentricTestFilter.cs index b1b7b5f0..648344d9 100644 --- a/src/TestModel/model/Filter/TestCentricTestFilter.cs +++ b/src/TestModel/model/Filter/TestCentricTestFilter.cs @@ -55,6 +55,8 @@ public IEnumerable AllCategories } } + public bool IsActive => _filters.Any(x => x.IsActive); + public void ClearAllFilters() { foreach (ITestFilter filter in _filters) diff --git a/src/TestModel/model/Filter/TextFilter.cs b/src/TestModel/model/Filter/TextFilter.cs index 217beec6..bb02748b 100644 --- a/src/TestModel/model/Filter/TextFilter.cs +++ b/src/TestModel/model/Filter/TextFilter.cs @@ -12,7 +12,7 @@ namespace TestCentric.Gui.Model.Filter /// /// Filters the TestNodes by matching a text (for example: Namespace, Class name or test method name - filter is case insensitive) /// - internal class TextFilter : ITestFilter + public class TextFilter : ITestFilter { private string _condition = string.Empty; @@ -24,6 +24,8 @@ public IEnumerable Condition set { _condition = value.FirstOrDefault(); } } + public bool IsActive => string.IsNullOrEmpty( _condition) == false; + public bool IsMatching(TestNode testNode) { if (string.IsNullOrEmpty(_condition)) diff --git a/src/TestModel/model/TestFilter.cs b/src/TestModel/model/TestFilter.cs index f044646e..9d0e2a0d 100644 --- a/src/TestModel/model/TestFilter.cs +++ b/src/TestModel/model/TestFilter.cs @@ -80,6 +80,35 @@ public static TestFilter MakeCategoryFilter(IList categories) return new TestFilter(sb.ToString()); } + /// + /// Creates a TestFilter which contains the IDs of all visible child nodes + /// + public static TestFilter MakeVisibleIdFilter(IEnumerable testNodes) + { + StringBuilder sb = new StringBuilder(""); + + foreach (TestNode test in testNodes) + MakeVisibleIdFilter(test, sb); + + sb.Append(""); + + return new TestFilter(sb.ToString()); + } + + private static void MakeVisibleIdFilter(TestNode testNode, StringBuilder sb) + { + // If testNode is not visible, don't add it or any child to filter + if (!testNode.IsVisible) + return; + + // Add only Id for leaf nodes + if (!testNode.IsProject && !testNode.IsSuite && testNode.Children.Count == 0) + sb.Append($"{testNode.Id}"); + + foreach (TestNode childNode in testNode.Children) + MakeVisibleIdFilter(childNode, sb); + } + public static TestFilter MakeNotFilter(TestFilter filter) { return new TestFilter($"{filter.InnerXml}"); diff --git a/src/TestModel/model/TestModel.cs b/src/TestModel/model/TestModel.cs index 904385a5..5c024bf5 100644 --- a/src/TestModel/model/TestModel.cs +++ b/src/TestModel/model/TestModel.cs @@ -680,6 +680,10 @@ private void RunTests(TestRunSpecification runSpec) if (!runSpec.CategoryFilter.IsEmpty) filter = TestFilter.MakeAndFilter(filter, runSpec.CategoryFilter); + // If a filter is active in the UI, a TestFilter must be created accordingly that contains the ID all visible children of the selected nodes. + if (Settings.Gui.TestTree.DisplayFormat == "NUNIT_TREE" && TestCentricTestFilter.IsActive) + filter = TestFilter.MakeVisibleIdFilter(runSpec.SelectedTests); + // We need to re-create the test runner because settings such // as debugging have already been passed to the test runner. // For performance reasons, we only do this if we did run diff --git a/src/TestModel/tests/Filter/CategoryFilterTests.cs b/src/TestModel/tests/Filter/CategoryFilterTests.cs new file mode 100644 index 00000000..aa597444 --- /dev/null +++ b/src/TestModel/tests/Filter/CategoryFilterTests.cs @@ -0,0 +1,175 @@ +// *********************************************************************** +// Copyright (c) Charlie Poole and TestCentric contributors. +// Licensed under the MIT License. See LICENSE file in root directory. +// *********************************************************************** + +using NSubstitute; +using NUnit.Framework; +using System.Collections.Generic; + +namespace TestCentric.Gui.Model.Filter +{ + [TestFixture] + internal class CategoryFilterTests + { + [Test] + public void Create_TestFilter_ConditionIsEmpty() + { + // 1. Arrange + Act + ITestModel testModel = Substitute.For(); + CategoryFilter filter = new CategoryFilter(testModel); + + // 2. Assert + Assert.That(filter.Condition, Is.Empty); + } + + [TestCase(new[] { "CategoryA" }, new[] { "CategoryA" })] + [TestCase(new[] { "CategoryA", "CategoryB" }, new[] { "CategoryB" })] + [TestCase(new[] { "CategoryB" }, new[] { "CategoryA", "CategoryB" })] + [TestCase(new[] { CategoryFilter.NoCategory }, new string[]{ })] + + public void IsMatching_CategoryMatchesCategoryFilter_ReturnsTrue(IList categoryFilter, IList testCategories) + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Condition = categoryFilter; + + string xml = CreateTestcaseXml("1", "TestA", testCategories); + TestNode testNode = new TestNode(xml); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.True); + } + + [TestCase(new[] { "CategoryA" }, new[] { "CategoryB" })] + [TestCase(new[] { "CategoryA" }, new[] { "" })] + [TestCase(new[] { CategoryFilter.NoCategory }, new[] { "CategoryB" })] + public void IsMatching_CategoryNotMatchesCategoryFilter_ReturnsFalse(IList categoryFilter, IList testCategories) + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Condition = categoryFilter; + + string xml = CreateTestcaseXml("1", "TestA", testCategories); + TestNode testNode = new TestNode(xml); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.False); + } + + [Test] + public void Init_Condition_ContainsAllCategories() + { + // 1. Arrange + var availableCategories = new List() { "CategoryA", "CategoryB" }; + ITestModel testModel = Substitute.For(); + testModel.AvailableCategories.Returns(availableCategories); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Condition = new[] { "CategoryA" }; + + // 2. Act + filter.Init(); + + // 3. Assert + Assert.That(filter.Condition, Has.Exactly(3).Items); + Assert.That(filter.Condition, Does.Contain("CategoryA")); + Assert.That(filter.Condition, Does.Contain("CategoryB")); + Assert.That(filter.Condition, Does.Contain(CategoryFilter.NoCategory)); + } + + [Test] + public void Reset_Condition_ContainsAllCategories() + { + // 1. Arrange + var availableCategories = new List() { "CategoryA", "CategoryB" }; + ITestModel testModel = Substitute.For(); + testModel.AvailableCategories.Returns(availableCategories); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Condition = new[] { "CategoryA" }; + + // 2. Act + filter.Reset(); + + // 3. Assert + Assert.That(filter.Condition, Has.Exactly(3).Items); + Assert.That(filter.Condition, Does.Contain("CategoryA")); + Assert.That(filter.Condition, Does.Contain("CategoryB")); + Assert.That(filter.Condition, Does.Contain(CategoryFilter.NoCategory)); + } + + [Test] + public void IsActive_Condition_IsSet_ReturnsTrue() + { + // 1. Arrange + var availableCategories = new List() { "CategoryA", "CategoryB" }; + ITestModel testModel = Substitute.For(); + testModel.AvailableCategories.Returns(availableCategories); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Init(); + + // 2. Act + filter.Condition = new[] { "CategoryA" }; + + // 3. Assert + Assert.That(filter.IsActive, Is.EqualTo(true)); + } + + [Test] + public void IsActive_FilterIsReset_ReturnsFalse() + { + // 1. Arrange + var availableCategories = new List() { "CategoryA", "CategoryB" }; + ITestModel testModel = Substitute.For(); + testModel.AvailableCategories.Returns(availableCategories); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Init(); + filter.Condition = new[] { "CategoryA" }; + + // 2. Act + filter.Reset(); + + // 3. Assert + Assert.That(filter.IsActive, Is.False); + } + + [Test] + public void IsActive_FilterIsInit_ReturnsFalse() + { + // 1. Arrange + var availableCategories = new List() { "CategoryA", "CategoryB" }; + ITestModel testModel = Substitute.For(); + testModel.AvailableCategories.Returns(availableCategories); + CategoryFilter filter = new CategoryFilter(testModel); + filter.Init(); + filter.Condition = new[] { "CategoryA" }; + + // 2. Act + filter.Init(); + + // 3. Assert + Assert.That(filter.IsActive, Is.False); + } + + private string CreateTestcaseXml(string testId, string testName, IList categories) + { + string str = $" "; + + str += " "; + foreach (string category in categories) + str += $" "; + str += " "; + + str += " "; + + return str; + } + } +} diff --git a/src/TestModel/tests/Filter/OutcomeFilterTests.cs b/src/TestModel/tests/Filter/OutcomeFilterTests.cs new file mode 100644 index 00000000..08e25f72 --- /dev/null +++ b/src/TestModel/tests/Filter/OutcomeFilterTests.cs @@ -0,0 +1,162 @@ +// *********************************************************************** +// Copyright (c) Charlie Poole and TestCentric contributors. +// Licensed under the MIT License. See LICENSE file in root directory. +// *********************************************************************** + +using System.Collections.Generic; +using NSubstitute; +using NUnit.Framework; +using NUnit.Framework.Internal; + +namespace TestCentric.Gui.Model.Filter +{ + [TestFixture] + internal class OutcomeFilterTests + { + [Test] + public void Create_TestFilter_ConditionIsEmpty() + { + // 1. Arrange + Act + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + + // 2. Assert + Assert.That(filter.Condition, Is.Empty); + } + + [TestCase(new[] { "Passed" }, "Passed")] + [TestCase(new[] { "Failed", "Passed" }, "Passed")] + [TestCase(new string[0] , "Passed")] + [TestCase(new[] { OutcomeFilter.AllOutcome }, "Passed")] + public void IsMatching_TestOutcomeMatchesOutcomeFilter_ReturnsTrue(IList outcomeFilter, string testOutcome) + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = outcomeFilter; + + TestNode testNode = new TestNode($""); + var resultNode = new ResultNode($""); + testModel.GetResultForTest(testNode.Id).Returns(resultNode); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.True); + } + + [TestCase(new[] { "Passed" }, "Failed")] + [TestCase(new[] { "Failed", "Passed" }, "Skipped")] + [TestCase(new[] { OutcomeFilter.NotRunOutcome }, "Passed")] + public void IsMatching_TestOutcomeNotMatchesOutcomeFilter_ReturnsFalse(IList outcomeFilter, string testOutcome) + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = outcomeFilter; + + TestNode testNode = new TestNode($""); + var resultNode = new ResultNode($""); + testModel.GetResultForTest(testNode.Id).Returns(resultNode); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.False); + } + + [TestCase(new[] { OutcomeFilter.NotRunOutcome }, "Passed")] + public void IsMatching_NoTestOutcomeMatchesOutcomeFilter_ReturnsTrue(IList outcomeFilter, string testOutcome) + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = outcomeFilter; + + TestNode testNode = new TestNode($""); + testModel.GetResultForTest(testNode.Id).Returns((ResultNode)null); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.True); + } + + [Test] + public void Init_ConditionIsEmpty() + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = new[] { "Failed" }; + + // 2. Act + filter.Init(); + + // 3. Assert + Assert.That(filter.Condition, Is.Empty); + } + + [Test] + public void Reset_ConditionIsEmpty() + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = new[] { "Failed" }; + + // 2. Act + filter.Reset(); + + // 3. Assert + Assert.That(filter.Condition, Is.Empty); + } + + [Test] + public void IsActive_Condition_IsSet_ReturnsTrue() + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + + // 2. Act + filter.Condition = new[] { "Passed" }; + + // 3. Assert + Assert.That(filter.IsActive, Is.EqualTo(true)); + } + + [Test] + public void IsActive_FilterIsReset_ReturnsFalse() + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = new[] { "Failed" }; + + // 2. Act + filter.Reset(); + + // 3. Assert + Assert.That(filter.IsActive, Is.False); + } + + [Test] + public void IsActive_FilterIsInit_ReturnsFalse() + { + // 1. Arrange + ITestModel testModel = Substitute.For(); + OutcomeFilter filter = new OutcomeFilter(testModel); + filter.Condition = new[] { "Failed" }; + + // 2. Act + filter.Init(); + + // 3. Assert + Assert.That(filter.IsActive, Is.False); + } + } +} diff --git a/src/TestModel/tests/TestCentricTestFilterTests.cs b/src/TestModel/tests/Filter/TestCentricTestFilterTests.cs similarity index 94% rename from src/TestModel/tests/TestCentricTestFilterTests.cs rename to src/TestModel/tests/Filter/TestCentricTestFilterTests.cs index adcda6e1..fbdd526c 100644 --- a/src/TestModel/tests/TestCentricTestFilterTests.cs +++ b/src/TestModel/tests/Filter/TestCentricTestFilterTests.cs @@ -9,9 +9,8 @@ using NSubstitute; using NUnit.Framework; using NUnit.Framework.Internal; -using TestCentric.Gui.Model.Filter; -namespace TestCentric.Gui.Model +namespace TestCentric.Gui.Model.Filter { [TestFixture] internal class TestCentricTestFilterTests @@ -320,7 +319,7 @@ public void FilterByCategory_TestNodesAreVisible(IList categoryFilter, I // Act TestCentricTestFilter testFilter = new TestCentricTestFilter(_model, () => { }); testFilter.Init(); - testFilter.CategoryFilter= categoryFilter; + testFilter.CategoryFilter = categoryFilter; // Assert foreach (string testId in expectedVisibleNodes) @@ -383,7 +382,7 @@ public void FilterByOutcomeCategoryAndText_TestNodesAreVisible(IList cat } private static object[] FilterByCategoryCategoryAndTextAllInvisibleTestCases = -{ + { new object[] { new[] { "Category_XY" }, new[] { OutcomeFilter.AllOutcome }, ""}, new object[] { new[] { "Category_1" }, new[] { "Passed", "Failed" }, "NamespaceXY"}, new object[] { new[] { "Category_3" }, new[] { OutcomeFilter.NotRunOutcome }, ""}, @@ -426,6 +425,48 @@ public void FilterByOutcomeCategoryAndText_AllNodesAreInvisible(IList ca AssertTestNodeIsInvisible(testNode); } + [Test] + public void IsActive_InitFilter_IsFalse() + { + // Arrange + TestCentricTestFilter testFilter = new TestCentricTestFilter(_model, () => { }); + testFilter.Init(); + + // Act + bool isActive = testFilter.IsActive; + + // Assert + Assert.That(isActive, Is.False); + } + + private static object[] IsActiveTestCases = +{ + new object[] { new[] { "Category_XY" }, new string[] { }, ""}, + new object[] { new string[] { }, new[] { "Passed", "Failed" }, ""}, + new object[] { new string[] { }, new string[] { }, "TestA"}, + }; + + [Test] + [TestCaseSource(nameof(IsActiveTestCases))] + public void IsActive_FilterIsSet_IsTrue(IList categoryFilter, IList outcomeFilter, string textFilter) + { + // Arrange + var testNode = new TestNode($""); + _model.LoadedTests.Returns(testNode); + + TestCentricTestFilter testFilter = new TestCentricTestFilter(_model, () => { }); + testFilter.Init(); + testFilter.CategoryFilter = categoryFilter; + testFilter.OutcomeFilter = outcomeFilter; + testFilter.TextFilter = textFilter; + + // Act + bool isActive = testFilter.IsActive; + + // Assert + Assert.That(isActive, Is.True); + } + private void AssertTestNodeIsInvisible(TestNode testNode) { Assert.That(testNode.IsVisible, Is.False, $"TestNode {testNode.Id} is not invisible."); @@ -435,7 +476,7 @@ private void AssertTestNodeIsInvisible(TestNode testNode) private TestNode GetTestNode(TestNode testNode, string testId) { - if (testNode.Id == testId) + if (testNode.Id == testId) return testNode; foreach (TestNode child in testNode.Children) diff --git a/src/TestModel/tests/Filter/TextFilterTests.cs b/src/TestModel/tests/Filter/TextFilterTests.cs new file mode 100644 index 00000000..eae936b4 --- /dev/null +++ b/src/TestModel/tests/Filter/TextFilterTests.cs @@ -0,0 +1,132 @@ +// *********************************************************************** +// Copyright (c) Charlie Poole and TestCentric contributors. +// Licensed under the MIT License. See LICENSE file in root directory. +// *********************************************************************** + +using NUnit.Framework; + +namespace TestCentric.Gui.Model.Filter +{ + [TestFixture] + internal class TextFilterTests + { + [Test] + public void Create_TestFilter_ConditionIsEmpty() + { + // 1. Arrange + Act + TextFilter filter = new TextFilter(); + + // 2. Assert + Assert.That(filter.Condition, Has.Exactly(1).EqualTo("")); + } + + [TestCase("", "")] + [TestCase(null, "")] + [TestCase("", "TestA")] + [TestCase("TestA", "TestA")] + [TestCase("TESTA", "TestA")] + [TestCase("A", "TestA")] + public void IsMatching_TestNodeNameMatchesFilterText_ReturnsTrue(string filterText, string nodeName) + { + // 1. Arrange + TextFilter filter = new TextFilter(); + filter.Condition = new[] { filterText }; + TestNode testNode = new TestNode($""); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.True); + } + + [TestCase("A", "")] + [TestCase("B", "TestA")] + [TestCase("TestAB", "TestA")] + public void IsMatching_TestNodeNameNotMatchesFilterText_ReturnsFalse(string filterText, string nodeName) + { + // 1. Arrange + TextFilter filter = new TextFilter(); + filter.Condition = new[] { filterText }; + TestNode testNode = new TestNode($""); + + // 2. Act + bool isMatch = filter.IsMatching(testNode); + + // 3. Assert + Assert.That(isMatch, Is.False); + } + + [Test] + public void Init_ConditionIsEmpty() + { + // 1. Arrange + TextFilter filter = new TextFilter(); + filter.Condition = new[] { "TextFilter" }; + + // 2. Act + filter.Init(); + + // 3. Assert + Assert.That(filter.Condition, Has.Exactly(1).EqualTo("")); + } + + [Test] + public void Reset_ConditionIsEmpty() + { + // 1. Arrange + TextFilter filter = new TextFilter(); + filter.Condition = new[] { "TextFilter" }; + + // 2. Act + filter.Reset(); + + // 3. Assert + Assert.That(filter.Condition, Has.Exactly(1).EqualTo("")); + } + + [TestCase("FilterText", true)] + [TestCase("A", true)] + [TestCase("", false)] + [TestCase(null, false)] + public void IsActive_Condition_IsSet_ReturnsTrue(string filterText, bool expectedIsActive) + { + // 1. Arrange + TextFilter filter = new TextFilter(); + + // 2. Act + filter.Condition = new[] { filterText }; + + // 3. Assert + Assert.That(filter.IsActive, Is.EqualTo(expectedIsActive)); + } + + [Test] + public void IsActive_FilterIsReset_ReturnsFalse() + { + // 1. Arrange + TextFilter filter = new TextFilter(); + filter.Condition = new[] { "FilterText" }; + + // 2. Act + filter.Reset(); + + // 3. Assert + Assert.That(filter.IsActive, Is.False); + } + + [Test] + public void IsActive_FilterIsInit_ReturnsFalse() + { + // 1. Arrange + TextFilter filter = new TextFilter(); + filter.Condition = new[] { "FilterText" }; + + // 2. Act + filter.Init(); + + // 3. Assert + Assert.That(filter.IsActive, Is.False); + } + } +} diff --git a/src/TestModel/tests/TestFilterTests.cs b/src/TestModel/tests/TestFilterTests.cs new file mode 100644 index 00000000..6e1f9e0f --- /dev/null +++ b/src/TestModel/tests/TestFilterTests.cs @@ -0,0 +1,144 @@ +// *********************************************************************** +// Copyright (c) Charlie Poole and TestCentric contributors. +// Licensed under the MIT License. See LICENSE file in root directory. +// *********************************************************************** + +using System.Collections.Generic; +using NUnit.Framework; + +namespace TestCentric.Gui.Model +{ + [TestFixture] + internal class TestFilterTests + { + [Test] + public void MakeVisibleIdFilter_NoSelectedNodes_ReturnsFilter() + { + // Arrange + var testNodes = new List(); + + // Act + TestFilter filter = TestFilter.MakeVisibleIdFilter(testNodes); + + // Assert + Assert.That(filter.XmlText, Is.EqualTo("")); + } + + [Test] + public void MakeVisibleIdFilter_AllTestNodesVisible_ReturnsFilter() + { + // Arrange + var testNodes = new List() + { + new TestNode(""), + new TestNode(""), + }; + + // Act + TestFilter filter = TestFilter.MakeVisibleIdFilter(testNodes); + + // Assert + Assert.That(filter.XmlText, Is.EqualTo("12")); + } + + [Test] + public void MakeVisibleIdFilter_TestNodesNotVisible_ReturnsFilter() + { + // Arrange + var testNodes = new List() + { + new TestNode("") { IsVisible = false }, + new TestNode("") { IsVisible = true }, + }; + + // Act + TestFilter filter = TestFilter.MakeVisibleIdFilter(testNodes); + + // Assert + Assert.That(filter.XmlText, Is.EqualTo("2")); + } + + private static object[] MakeVisibleIdFilter = +{ + new object[] { new[] { "3-1000", "3-1100", "3-1110", "3-1111" }, new[] { "3-1111" }, new[] { "3-1000", "3-1100", "3-1110", "3-1112" } }, + new object[] { new[] { "3-1000", "3-1200", "3-1210", "3-1211", "3-1212" }, new[] { "3-1211", "3-1211" }, new[] { "3-1000", "3-1100", "3-1111", "3-1112", "3-1210" } }, + new object[] { new[] { "3-1000", "3-1300", "3-1310", "3-1312", "3-1320", "3-1322" }, new[] { "3-1312", "3-1322" }, new[] { "3-1000", "3-1300", "3-1310", "3-1311", "3-1321" } }, + new object[] { new[] { "3-1000", "3-1300", "3-1320", "3-1322" }, new[] { "3-1322" }, new[] { "3-1000", "3-1300", "3-1310", "3-1311", "3-1312", "3-1321" } }, + }; + + [Test] + [TestCaseSource(nameof(MakeVisibleIdFilter))] + public void MakeVisibleIdFilter_TestNodesHierarchie_ReturnsFilter(IList visibleNodeIds, IList expectedIds, IList expectedIdsNotInFilter) + { + // Arrange + TestNode testNode = new TestNode( + CreateTestSuiteXml("3-1000", + CreateTestSuiteXml("3-1100", + CreateTestFixtureXml("3-1110", + CreateTestcaseXml("3-1111"), + CreateTestcaseXml("3-1112"))) + + CreateTestSuiteXml("3-1200", + CreateTestFixtureXml("3-1210", + CreateTestcaseXml("3-1211"), + CreateTestcaseXml("3-1212"))), + CreateTestSuiteXml("3-1300", + CreateTestFixtureXml("3-1310", + CreateTestcaseXml("3-1311"), + CreateTestcaseXml("3-1312")) + + CreateTestFixtureXml("3-1320", + CreateTestcaseXml("3-1321"), + CreateTestcaseXml("3-1322"))))); + + SetVisibleNodes(testNode, visibleNodeIds); + + // Act + TestFilter filter = TestFilter.MakeVisibleIdFilter(new[] { testNode }); + + // Assert + string xmlText = filter.XmlText; + + foreach (string id in expectedIds) + Assert.That(xmlText, Does.Contain($"{id}")); + + foreach (string id in expectedIdsNotInFilter) + Assert.That(xmlText, Does.Not.Contain($"{id}")); + } + + private void SetVisibleNodes(TestNode testNode, IList visibleNodeIds) + { + testNode.IsVisible = visibleNodeIds.Contains(testNode.Id); + + foreach(TestNode childNode in testNode.Children) + SetVisibleNodes(childNode, visibleNodeIds); + } + + private string CreateTestcaseXml(string testId) + { + string str = $" "; + return str; + } + + private string CreateTestFixtureXml(string testId, params string[] testCases) + { + string str = $" "; + + foreach (string testCase in testCases) + str += testCase; + + str += ""; + + return str; + } + + private string CreateTestSuiteXml(string testId, params string[] testSuites) + { + string str = $" "; + foreach (string testSuite in testSuites) + str += testSuite; + + str += ""; + + return str; + } + } +}