public int Compare(MatchedFileSystemItem x, MatchedFileSystemItem y)
        {
            int? validityResult = CompareValidity(x, y);
            if (validityResult != null)
            {
                return validityResult.Value;
            }

            bool xIsPerfectMatch = x.MatchedItemName.Count == 1;
            bool yIsPerfectMatch = y.MatchedItemName.Count == 1;

            if(xIsPerfectMatch && !yIsPerfectMatch)
            {
                return -1;
            }

            if (!xIsPerfectMatch && yIsPerfectMatch)
            {
                return 1;
            }

            if (x.FullPath.Length != y.FullPath.Length)
            {
                return x.FullPath.Length.CompareTo(y.FullPath.Length);
            }

            return string.Compare(x.FullPath, y.FullPath, StringComparison.CurrentCulture);
        }
        public MatchModel GetMatchModel(MatchedFileSystemItem match)
        {
            //Clone the matched item name
            MatchString matchedItemName = new MatchString(match.MatchedItemName);
            string path = string.Format(CultureInfo.InvariantCulture, " -> {0}", match.FullPath);
            matchedItemName.Add(new MatchSubstring(path, false));

            return new MatchModel(this, matchedItemName, match.FullPath);
        }
        private MatchedFileSystemItem GetMatchedItem(FileSystemItem item, Regex searchRegex)
        {
            List<MatchSubstring> substrings = GetMatchSubstrings(item.Name, searchRegex);
            if (substrings == null)
            {
                return null;
            }

            MatchedFileSystemItem matchedItem = new MatchedFileSystemItem(item, new MatchString(substrings));

            return matchedItem;
        }
        private static int? CompareValidity(MatchedFileSystemItem x, MatchedFileSystemItem y)
        {
            int? nullComparison = CompareByNull(x, y);
            if (nullComparison != null)
            {
                return nullComparison.Value;
            }

            int? matchNullComparison = CompareByNull(x.MatchedItemName, y.MatchedItemName);
            if (matchNullComparison != null)
            {
                return matchNullComparison.Value;
            }

            int? pathNullComparison = CompareByNull(x.FullPath, y.FullPath);
            if (pathNullComparison != null)
            {
                return pathNullComparison.Value;
            }

            return null;
        }
        public IEnumerable<TestCaseData> GetMatchCases()
        {
            const string rootPath = @"C:\";

            FileSystemItem item;
            string searchText;
            MatchString matchString;
            MatchedFileSystemItem expectedMatch;
            TestCaseData testCaseData;

            yield return CreateTestCaseData("my doc", "y d", null, "Match just from word start (first word violation)");

            yield return CreateTestCaseData("my doc", "m d", "my d", "Simple match of two words");

            yield return CreateTestCaseData("my own doc", "m d", null, "Match just neighboring words");

            yield return CreateTestCaseData("my doc", "m o", null, "Match just from word start (second word violation)");

            item = new FileSystemItem(rootPath + "my own doc");
            searchText = "ow Do";
            matchString = new MatchString
                              {
                                  new MatchSubstring("my ", false),
                                  new MatchSubstring("own do", true),
                                  new MatchSubstring("c", false),
                              };
            expectedMatch = new MatchedFileSystemItem(item, matchString);
            testCaseData = new TestCaseData(item, searchText, expectedMatch).SetName("Simple match from the second word");
            yield return testCaseData;

            item = new FileSystemItem(rootPath + "my oWn dOc");
            searchText = "Ow Do";
            matchString = new MatchString
                              {
                                  new MatchSubstring("my ", false),
                                  new MatchSubstring("oWn dO", true),
                                  new MatchSubstring("c", false),
                              };
            expectedMatch = new MatchedFileSystemItem(item, matchString);
            testCaseData = new TestCaseData(item, searchText, expectedMatch).SetName("Simple match from the second word (ignored case)");
            yield return testCaseData;

            yield return CreateTestCaseData("myDoc", "m dO", "myDo", "Match camel/pascal casing");

            yield return CreateTestCaseData("my    Doc", "m do", "my    Do", "Ignore multiple spaces in item name");

            yield return CreateTestCaseData("my Doc", "m   do", "my Do", "Ignore multiple spaces in search text");

            item = new FileSystemItem(rootPath + "myOwnDoc");
            searchText = "o do";
            matchString = new MatchString
                              {
                                  new MatchSubstring("my", false),
                                  new MatchSubstring("OwnDo", true),
                                  new MatchSubstring("c", false)
                              };
            expectedMatch = new MatchedFileSystemItem(item, matchString);
            testCaseData = new TestCaseData(item, searchText, expectedMatch).SetName("Match camel/pascal casing in the middle");
            yield return testCaseData;

            yield return CreateTestCaseData("mydoc", "m do", null, "Do not match words not separated with space or camel case");
        }
        private void MatchesCorrect(FileSystemItem item, string searchText, MatchedFileSystemItem expectedMatch)
        {
            List<FileSystemItem> items = new List<FileSystemItem> {item};

            List<MatchedFileSystemItem> actualMatches = _matchSearcher.GetMatches(items, searchText);

            bool matchExistenceCorrect = ((expectedMatch == null) && (ListUtility.IsNullOrEmpty(actualMatches))) ||
                                         ((expectedMatch != null) && (!ListUtility.IsNullOrEmpty(actualMatches)));

            Assert.That(matchExistenceCorrect, Is.True);

            if (expectedMatch == null)
            {
                return;
            }

            Assert.That(MatchesEqual(actualMatches[0], expectedMatch));
        }
        private TestCaseData CreateTestCaseData(string folderName, string searchText, string matchedSubstring, string testName)
        {
            FileSystemItem item = new FileSystemItem("C:\\" + folderName);
            MatchedFileSystemItem expectedMatch;
            if (string.IsNullOrEmpty(matchedSubstring))
            {
                expectedMatch = null;
            }
            else
            {
                MatchString matchString = new MatchString
                                  {
                                      new MatchSubstring(matchedSubstring, true),
                                      new MatchSubstring(folderName.Substring(matchedSubstring.Length), false),
                                  };
                expectedMatch = new MatchedFileSystemItem(item, matchString);
            }

            TestCaseData testCaseData = new TestCaseData(item, searchText, expectedMatch).SetName(testName);
            return testCaseData;
        }
        private static bool MatchesEqual(MatchedFileSystemItem actualMatch, MatchedFileSystemItem expectedMatch)
        {
            bool result =
                string.Equals(actualMatch.FullPath, expectedMatch.FullPath, StringComparison.Ordinal) &&
                string.Equals(actualMatch.Name, expectedMatch.Name, StringComparison.Ordinal) &&
                MatchedStringsEqual(actualMatch.MatchedItemName, expectedMatch.MatchedItemName);

            return result;
        }
 public void GetMatches_WithSpecialSymbols_MatchesCorrect(FileSystemItem item, string searchText, MatchedFileSystemItem expectedMatch)
 {
     MatchesCorrect(item, searchText, expectedMatch);
 }