private Feature ConvertToFeature(MethodInfo test)
 {
     return(new Feature(test, FeatureTestAttributeHelper.GetDisplayName(test))
     {
         Description = this.GetDescription(test)
     });
 }
        private async Task <FeatureTestResult> RunTestAsync(MethodInfo test, Type adapterType, IEnumerable <FeatureTestRun> dependencies)
        {
            var specialCase = this.GetSpecialCase(test, adapterType)
                              ?? this.GetSpecialCase(test.DeclaringType, adapterType);

            if (specialCase != null && specialCase.Skip)
            {
                return(new FeatureTestResult(FeatureTestResultKind.SkippedDueToSpecialCase, this.attributeCleaner.CleanWhitespace(specialCase.Comment)));
            }

            foreach (var dependency in dependencies.OrderBy(d => d.Method.Name))
            {
                var result = await dependency.Task;
                if (result.Kind != FeatureTestResultKind.Success)
                {
                    var className = FeatureTestAttributeHelper.GetDisplayName(dependency.Method.DeclaringType);
                    var testName  = FeatureTestAttributeHelper.GetDisplayName(dependency.Method);

                    var skippedComment = string.Format("Skipped as {0} ({1}) is not supported by this library.", testName, className);
                    return(new FeatureTestResult(FeatureTestResultKind.SkippedDueToDependency, skippedComment));
                }
            }

            var instance = Activator.CreateInstance(test.DeclaringType);

            using (instance as IDisposable) {
                try {
                    await Task.Run(() => test.Invoke(instance, new object[] { LibraryProvider.CreateAdapter(adapterType) }));
                }
                catch (Exception ex) {
                    var useful = ToUsefulException(ex);
                    if (useful is SkipException)
                    {
                        return(new FeatureTestResult(FeatureTestResultKind.SkippedDueToSpecialCase, useful.Message));
                    }

                    return(new FeatureTestResult(FeatureTestResultKind.Failure, exception: useful));
                }
            }

            var comment = specialCase != null?this.attributeCleaner.CleanWhitespace(specialCase.Comment) : null;

            return(new FeatureTestResult(FeatureTestResultKind.Success, comment));
        }
        public IEnumerable <FeatureTable> GetTables(Assembly featureTestAssembly)
        {
            var testRuns   = this.runner.RunAllTests(featureTestAssembly).ToDictionary(r => new { Test = r.Method, LibraryType = r.AdapterType });
            var testGroups = testRuns.Keys
                             .Select(k => k.Test)
                             .Distinct()
                             .GroupBy(m => m.DeclaringType)
                             .OrderBy(g => FeatureTestAttributeHelper.GetDisplayOrder(g.Key))
                             .ToArray();

            var libraries = LibraryProvider.GetAdapters(featureTestAssembly).ToArray();

            foreach (var group in testGroups)
            {
                var features = group.ToDictionary(m => m, this.ConvertToFeature);
                var table    = new FeatureTable(FeatureTestAttributeHelper.GetDisplayName(group.Key), libraries, features.Values)
                {
                    Description = this.GetDescription(@group.Key),
                    Scoring     = FeatureTestAttributeHelper.GetScoring(@group.Key)
                };

                var resultApplyTasks = new List <Task>();
                foreach (var test in group.OrderBy(FeatureTestAttributeHelper.GetDisplayOrder))
                {
                    foreach (var library in libraries)
                    {
                        var cell = table[library, test];
                        var run  = testRuns[new { Test = test, LibraryType = library.GetType() }];

                        resultApplyTasks.Add(this.ApplyRunResultToCell(cell, run.Task));
                    }
                }

                Task.WaitAll(resultApplyTasks.ToArray());
                yield return(table);
            }
        }