예제 #1
0
        public void EmptyExeFilterAcceptsAll()
        {
            CatchAdapterSettings settings = new CatchAdapterSettings();

            Assert.IsTrue(settings.IncludeTestExe("blaa"));
            Assert.IsTrue(settings.IncludeTestExe("Test.exe"));
        }
예제 #2
0
        public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink)
        {
            logger.SendMessage(TestMessageLevel.Informational, "Catch Discover in process ...");

            // Load settings from the discovery context.
            CatchAdapterSettings settings = CatchSettingsProvider.LoadSettings(discoveryContext.RunSettings);

            try
            {
                foreach (var src in sources.Where(src => settings.IncludeTestExe(src)))
                {
                    logger.SendMessage(TestMessageLevel.Informational, $"Processing catch test source: '{src}'...");

                    var testCases = CreateTestCases(src);
                    foreach (var t in testCases)
                    {
                        discoverySink.SendTestCase(t);
                        logger.SendMessage(TestMessageLevel.Informational, t.DisplayName);
                    }
                }
            }
            catch (Exception ex)
            {
                // Just log the error message.
                logger.SendMessage(TestMessageLevel.Error, ex.Message);
            }
        }
예제 #3
0
        public void ExcludeExeFilterRejectsOnlyMatching()
        {
            CatchAdapterSettings settings = new CatchAdapterSettings();

            settings.TestExeExclude.Add("blaa");
            settings.TestExeExclude.Add(@".*\.exe");

            Assert.IsFalse(settings.IncludeTestExe("blaa"));
            Assert.IsFalse(settings.IncludeTestExe("Test.exe"));
            Assert.IsTrue(settings.IncludeTestExe("Hippopotamus"));
        }
예제 #4
0
        public void IncludeExcludeTogether()
        {
            CatchAdapterSettings settings = new CatchAdapterSettings();

            settings.TestExeInclude.Add(@".*\.exe");
            settings.TestExeExclude.Add(@"bl(aa|uu)");

            Assert.IsTrue(settings.IncludeTestExe("Test.exe"));
            Assert.IsFalse(settings.IncludeTestExe("Hippopotamus"));
            Assert.IsFalse(settings.IncludeTestExe("blaa.exe"));
            Assert.IsFalse(settings.IncludeTestExe("bluu.exe"));
            Assert.IsTrue(settings.IncludeTestExe("blii.exe"));
        }
예제 #5
0
        public static IList <TestCase> CreateTestCases(string exeName, CatchAdapterSettings settings)
        {
            var testCases = new List <TestCase>();

            // Use the directory of the executable as the working directory.
            string workingDirectory = System.IO.Path.GetDirectoryName(exeName);

            var output = ProcessRunner.RunProcess(exeName, "--list-tests --verbosity high", workingDirectory);

            foreach (var test in ParseListing(exeName, settings, output))
            {
                testCases.Add(test);
            }

            return(testCases);
        }
예제 #6
0
        private static IEnumerable <TestCase> ParseListing(string exeName, CatchAdapterSettings settings, IList <string> lines)
        {
            // We manually enumerate through the lines of the output.
            IEnumerator <string> line = lines.GetEnumerator();

            // The first line should be fixed.
            if (!line.MoveNext() || line.Current != "All available test cases:")
            {
                yield break;
                //throw new Exception( "Unexpected line in catch output: " + line.Current );
            }

            // Split output to groups of lines related to the same test case.
            // We detect groups by indentation.
            var currentGroup = new List <string>();
            int lastIndent   = 0;

            while (line.MoveNext())
            {
                // A new group begins when indent drops.
                // If there is no indent, we are at the end.
                int indent = line.Current.Length - line.Current.TrimStart().Length;
                if (indent > 0 && indent < lastIndent)
                {
                    // Yield the finished group.
                    yield return(LineGroupToTestCase(exeName, settings, currentGroup));

                    // Begin a new group.
                    currentGroup = new List <string>();
                }

                // Add the line to the current group.
                currentGroup.Add(line.Current.Trim());

                // Remember indent.
                lastIndent = indent;
            }

            // Yield the final group.
            yield return(LineGroupToTestCase(exeName, settings, currentGroup));
        }
예제 #7
0
        private static TestCase LineGroupToTestCase(string exeName, CatchAdapterSettings settings, IList <string> lineGroup)
        {
            // The group needs to have at least three lines.
            if (lineGroup.Count < 3)
            {
                string lines = lineGroup.Aggregate("", (add, acc) => add + "\n" + acc);
                throw new Exception(string.Format("Unexpectedly few lines in catch output group: '{0}'", lines));
            }

            // Get the name.
            string name = lineGroup[0];

            // If the line info contains a long full path,
            // catch may have wrapped it to multiple lines.
            // We have to combine them into one.
            string lineInfoString   = lineGroup[1];
            int    lastLineInfoLine = 2;

            for ( ; lastLineInfoLine < lineGroup.Count; lastLineInfoLine++)
            {
                // When we have something that looks like a source line information,
                // be satisfied with it. Otherwise append the next line to it.
                if (lineInfoPattern.IsMatch(lineInfoString))
                {
                    break;
                }
                else
                {
                    lineInfoString += lineGroup[lastLineInfoLine];
                }
            }

            // Parse line info with regex.
            var lineInfoMatch = lineInfoPattern.Match(lineInfoString);

            if (!lineInfoMatch.Success)
            {
                throw new Exception(String.Format("Could not parse line info from '{0}'.", lineInfoString));
            }

            string path       = lineInfoMatch.Groups["path"].Value;
            int    lineNumber = Int32.Parse(lineInfoMatch.Groups["line"].Value);

            // if the path isn't rooted, try to fix it up so that we can get back to the test source
            if (!System.IO.Path.IsPathRooted(path))
            {
                string exeDir = System.IO.Path.GetDirectoryName(exeName);

                // TODO -- add the solution root to the list, no idea how to get to it if we even can
                List <string> maybePathRoots = settings.TestSourcePathRoots.ToList();
                maybePathRoots.Add(exeDir);
                maybePathRoots.Add(System.IO.Directory.GetCurrentDirectory());
                foreach (string pathRoot in maybePathRoots)
                {
                    if (pathRoot == null)
                    {
                        continue;
                    }

                    string maybePath = System.IO.Path.Combine(pathRoot, path);
                    if (System.IO.File.Exists(maybePath))
                    {
                        path = maybePath;
                        break;
                    }
                }
            }

            // Construct the test.
            TestCase test = new TestCase(name, new Uri(TestExecutor.ExecutorUriString), exeName);

            test.CodeFilePath = path;
            test.LineNumber   = lineNumber;

            // Turn tags to traits.

            // Catch tags are enclosed in square brackets.
            Regex tagPattern = new Regex(@"\[([^]]+)\]");

            // Look at all lines after the line info.
            for (int i = lastLineInfoLine + 1; i < lineGroup.Count; ++i)
            {
                // Find all things that look like catch tags.
                foreach (Match match in tagPattern.Matches(lineGroup[i]))
                {
                    // Create the tags as traits with empty values.
                    string tag = match.Groups[1].Value;
                    test.Traits.Add(new Trait(tag, ""));
                }
            }

            return(test);
        }