private ICollection <DeveroomTag> ParseInternal(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, DeveroomConfiguration deveroomConfiguration)
        {
            var dialectProvider = SpecFlowGherkinDialectProvider.Get(deveroomConfiguration.DefaultFeatureLanguage);
            var parser          = new DeveroomGherkinParser(dialectProvider, _monitoringService);

            parser.ParseAndCollectErrors(fileSnapshot.GetText(), _logger,
                                         out var gherkinDocument, out var parserErrors);

            var result = new List <DeveroomTag>();

            if (gherkinDocument != null)
            {
                AddGherkinDocumentTags(fileSnapshot, bindingRegistry, gherkinDocument, result);
            }

            foreach (var parserException in parserErrors)
            {
                var line       = GetSnapshotLine(parserException.Location, fileSnapshot);
                var startPoint = GetColumnPoint(line, parserException.Location);
                var span       = new SnapshotSpan(startPoint, line.End);

                result.Add(new DeveroomTag(DeveroomTagTypes.ParserError,
                                           span, parserException.Message));
            }

            return(result);
        }
        protected ProjectBindingRegistry CreateSut()
        {
            var projectBindingRegistry = new ProjectBindingRegistry();

            projectBindingRegistry.StepDefinitions = _stepDefinitionBindings.ToArray();
            return(projectBindingRegistry);
        }
        private List <DeveroomTag> ReParse(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, DeveroomConfiguration configuration)
        {
            var tags = new List <DeveroomTag>(_deveroomTagParser.Parse(fileSnapshot, bindingRegistry, configuration));

            tags.Sort((t1, t2) => t1.Span.Start.Position.CompareTo(t2.Span.Start.Position));
            return(tags);
        }
Example #4
0
        private void AddRuleBlockTag(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, Rule rule, DeveroomTag featureTag)
        {
            var lastStepsContainer = rule.StepsContainers().LastOrDefault();
            var lastLine           = lastStepsContainer != null?
                                     GetScenarioDefinitionLastLine(lastStepsContainer) :
                                         rule.Location.Line;

            var ruleTag = CreateDefinitionBlockTag(rule,
                                                   DeveroomTagTypes.RuleBlock, fileSnapshot,
                                                   lastLine, featureTag);

            foreach (var stepsContainer in rule.StepsContainers())
            {
                AddScenarioDefinitionBlockTag(fileSnapshot, bindingRegistry, stepsContainer, ruleTag);
            }
        }
        public void WhenTheBindingDiscoveryPerformed()
        {
            var projectScope = GetProjectScope();

            foreach (var step in _projectScopeConfigurationSteps)
            {
                step(projectScope);
            }

            var discoveryService = projectScope.GetDiscoveryService();

            discoveryService.Should().NotBeNull("The DiscoveryService should be available");

            Wait.For(() =>
            {
                (_bindingRegistry = discoveryService.GetBindingRegistry())
                .Should().NotBeNull("binding should be discovered");
            }, 20000);
        }
Example #6
0
        private DeveroomTag GetFeatureTags(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, Feature feature)
        {
            var featureTag = CreateDefinitionBlockTag(feature, DeveroomTagTypes.FeatureBlock, fileSnapshot,
                                                      fileSnapshot.LineCount);

            foreach (var block in feature.Children)
            {
                if (block is StepsContainer stepsContainer)
                {
                    AddScenarioDefinitionBlockTag(fileSnapshot, bindingRegistry, stepsContainer, featureTag);
                }
                else if (block is Rule rule)
                {
                    AddRuleBlockTag(fileSnapshot, bindingRegistry, rule, featureTag);
                }
            }

            return(featureTag);
        }
        public IEnumerable <StepDefinitionUsage> FindUsagesFromContent(ProjectStepDefinitionBinding[] stepDefinitions,
                                                                       string featureFileContent, string featureFilePath, DeveroomConfiguration configuration)
        {
            var dialectProvider = SpecFlowGherkinDialectProvider.Get(configuration.DefaultFeatureLanguage);
            var parser          = new DeveroomGherkinParser(dialectProvider, _monitoringService);

            parser.ParseAndCollectErrors(featureFileContent, _logger,
                                         out var gherkinDocument, out _);

            var featureNode = gherkinDocument?.Feature;

            if (featureNode == null)
            {
                yield break;
            }

            var dummyRegistry = new ProjectBindingRegistry
            {
                StepDefinitions = stepDefinitions
            };

            var featureContext = new UsageFinderContext(featureNode);

            foreach (var scenarioDefinition in featureNode.FlattenStepsContainers())
            {
                var context = new UsageFinderContext(scenarioDefinition, featureContext);
                foreach (var step in scenarioDefinition.Steps)
                {
                    var matchResult = dummyRegistry.MatchStep(step, context);
                    if (matchResult == null)
                    {
                        continue; // this will not happen
                    }
                    if (matchResult.HasDefined)
                    {
                        yield return(new StepDefinitionUsage(
                                         GetSourceLocation(step, featureFilePath), step));
                    }
                }
            }
        }
        public ICollection <DeveroomTag> Parse(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, DeveroomConfiguration configuration)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            try
            {
                return(ParseInternal(fileSnapshot, bindingRegistry, configuration));
            }
            catch (Exception ex)
            {
                _logger.LogException(_monitoringService, ex, "Unhandled parsing error");
                return(new List <DeveroomTag>());
            }
            finally
            {
                stopwatch.Stop();
                _logger.LogVerbose($"Parsed buffer v{fileSnapshot.Version.VersionNumber} in {stopwatch.ElapsedMilliseconds}ms on thread {Thread.CurrentThread.ManagedThreadId}");
            }
        }
        private void AddGherkinDocumentTags(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry,
                                            DeveroomGherkinDocument gherkinDocument, List <DeveroomTag> result)
        {
            var documentTag = new DeveroomTag(DeveroomTagTypes.Document, new SnapshotSpan(fileSnapshot, 0, fileSnapshot.Length), gherkinDocument);

            result.Add(documentTag);

            if (gherkinDocument.Feature != null)
            {
                var featureTag = GetFeatureTags(fileSnapshot, bindingRegistry, gherkinDocument.Feature);
                result.AddRange(GetAllTags(featureTag));
            }

            if (gherkinDocument.Comments != null)
            {
                foreach (var comment in gherkinDocument.Comments)
                {
                    result.Add(new DeveroomTag(DeveroomTagTypes.Comment,
                                               GetTextSpan(fileSnapshot, comment.Location, comment.Text)));
                }
            }
        }
        private DeveroomTag GetFeatureTags(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, Feature feature)
        {
            var featureTag = CreateDefinitionBlockTag(feature, DeveroomTagTypes.FeatureBlock, fileSnapshot,
                                                      fileSnapshot.LineCount);

            foreach (var scenarioDefinition in feature.StepsContainers())
            {
                var scenarioDefinitionTag = CreateDefinitionBlockTag(scenarioDefinition,
                                                                     DeveroomTagTypes.ScenarioDefinitionBlock, fileSnapshot,
                                                                     GetScenarioDefinitionLastLine(scenarioDefinition), featureTag);

                foreach (var step in scenarioDefinition.Steps)
                {
                    var stepTag = scenarioDefinitionTag.AddChild(new DeveroomTag(DeveroomTagTypes.StepBlock,
                                                                                 GetBlockSpan(fileSnapshot, step.Location, GetStepLastLine(step)), step));

                    stepTag.AddChild(
                        new DeveroomTag(DeveroomTagTypes.StepKeyword,
                                        GetTextSpan(fileSnapshot, step.Location, step.Keyword),
                                        step.Keyword));

                    if (step.Argument is DataTable dataTable)
                    {
                        var dataTableBlockTag = new DeveroomTag(DeveroomTagTypes.DataTable,
                                                                GetBlockSpan(fileSnapshot, dataTable.Rows.First().Location,
                                                                             dataTable.Rows.Last().Location.Line),
                                                                dataTable);
                        stepTag.AddChild(dataTableBlockTag);
                        var dataTableHeader = dataTable.Rows.FirstOrDefault();
                        if (dataTableHeader != null)
                        {
                            TagRowCells(fileSnapshot, dataTableHeader, dataTableBlockTag, DeveroomTagTypes.DataTableHeader);
                        }
                    }
                    else if (step.Argument is DocString docString)
                    {
                        stepTag.AddChild(
                            new DeveroomTag(DeveroomTagTypes.DocString,
                                            GetBlockSpan(fileSnapshot, docString.Location,
                                                         GetStepLastLine(step)),
                                            docString));
                    }

                    if (scenarioDefinition is ScenarioOutline)
                    {
                        AddPlaceholderTags(fileSnapshot, stepTag, step);
                    }

                    var match = bindingRegistry?.MatchStep(step, scenarioDefinitionTag);
                    if (match != null)
                    {
                        if (match.HasDefined || match.HasAmbiguous)
                        {
                            stepTag.AddChild(new DeveroomTag(DeveroomTagTypes.DefinedStep,
                                                             GetTextSpan(fileSnapshot, step.Location, step.Text, offset: step.Keyword.Length),
                                                             match));
                            if (!(scenarioDefinition is ScenarioOutline) || !step.Text.Contains("<"))
                            {
                                var parameterMatch = match.Items.FirstOrDefault(m => m.ParameterMatch != null)
                                                     ?.ParameterMatch;
                                AddParameterTags(fileSnapshot, parameterMatch, stepTag, step);
                            }
                        }

                        if (match.HasUndefined)
                        {
                            stepTag.AddChild(new DeveroomTag(DeveroomTagTypes.UndefinedStep,
                                                             GetTextSpan(fileSnapshot, step.Location, step.Text, offset: step.Keyword.Length),
                                                             match));
                        }

                        if (match.HasErrors)
                        {
                            stepTag.AddChild(new DeveroomTag(DeveroomTagTypes.BindingError,
                                                             GetTextSpan(fileSnapshot, step.Location, step.Text, offset: step.Keyword.Length),
                                                             match.GetErrorMessage()));
                        }
                    }
                }

                if (scenarioDefinition is ScenarioOutline scenarioOutline)
                {
                    foreach (var scenarioOutlineExample in scenarioOutline.Examples)
                    {
                        var examplesBlockTag = CreateDefinitionBlockTag(scenarioOutlineExample,
                                                                        DeveroomTagTypes.ExamplesBlock, fileSnapshot,
                                                                        GetExamplesLastLine(scenarioOutlineExample), scenarioDefinitionTag);
                        if (scenarioOutlineExample.TableHeader != null)
                        {
                            TagRowCells(fileSnapshot, scenarioOutlineExample.TableHeader, examplesBlockTag, DeveroomTagTypes.ScenarioOutlinePlaceholder);
                        }
                    }
                }
            }

            return(featureTag);
        }
        private ProjectStepDefinitionBinding[] GetStepDefinitions(string fileName, SnapshotPoint triggerPoint, ProjectBindingRegistry bindingRegistry)
        {
            if (bindingRegistry == null)
            {
                return(new ProjectStepDefinitionBinding[0]);
            }

            return(bindingRegistry.StepDefinitions
                   .Where(sd => sd.Implementation?.SourceLocation != null &&
                          sd.Implementation.SourceLocation.SourceFile == fileName &&
                          IsTriggerPointInStepDefinition(sd, triggerPoint))
                   .ToArray());
        }