public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, ScenarioOutlineExamplesRow examplesRow, IGherkinFileScope fileScope, bool debug)
 {
     var line = currentScenario.KeywordLine;
     if (examplesRow != null && examplesRow.BlockRelativeLine >= 0)
         line += examplesRow.BlockRelativeLine;
     return RunInCurrentContext(VsxHelper.GetFileName(projectItem), debug, line);
 }
 public GherkinTextBufferPartialParserListener(GherkinDialect gherkinDialect, ITextSnapshot textSnapshot, IProjectScope projectScope, IGherkinFileScope previousScope, int changeLastLine, int changeLineDelta)
     : base(gherkinDialect, textSnapshot, projectScope)
 {
     this.previousScope = previousScope;
     this.changeLastLine = changeLastLine;
     this.changeLineDelta = changeLineDelta;
 }
 public GherkinTextBufferPartialParserListener(GherkinDialect gherkinDialect, ITextSnapshot textSnapshot, GherkinFileEditorClassifications classifications, IGherkinFileScope previousScope, int changeLastLine, int changeLineDelta)
     : base(gherkinDialect, textSnapshot, classifications)
 {
     this.previousScope = previousScope;
     this.changeLastLine = changeLastLine;
     this.changeLineDelta = changeLineDelta;
 }
        private IScenarioBlock GetCurrentScenario(GherkinLanguageService languageService, int currentLine, out IGherkinFileScope fileScope)
        {
            fileScope = languageService.GetFileScope();
            if (fileScope == null)
                return null;

            return fileScope.GetScenarioBlockFromPosition(currentLine);
        }
예제 #5
0
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope, bool debug)
        {
            var testRunnerGateway = GetCurrentTestRunnerGateway(projectItem.ContainingProject);
            if (testRunnerGateway == null)
                return false;

            return testRunnerGateway.RunScenario(projectItem, currentScenario, fileScope, debug);
        }
예제 #6
0
 public GherkinFileScopeChange(IGherkinFileScope gherkinFileScope, bool languageChanged, bool entireScopeChanged, IEnumerable<IGherkinFileBlock> changedBlocks, IEnumerable<IGherkinFileBlock> shiftedBlocks)
 {
     GherkinFileScope = gherkinFileScope;
     LanguageChanged = languageChanged;
     EntireScopeChanged = entireScopeChanged;
     ChangedBlocks = changedBlocks;
     ShiftedBlocks = shiftedBlocks;
 }
예제 #7
0
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope,
                                bool debug)
        {
            if (IsAllowDebugGeneratedFilesSet(projectItem))
                return runnerGateway_CodeBehind.RunScenario(projectItem, currentScenario, fileScope, debug);

            return runnerGateway_TestWindowInvoke.RunScenario(projectItem, currentScenario, fileScope, debug);
        }
예제 #8
0
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope, bool debug)
        {
            if (fileScope.HeaderBlock == null)
                return false;

            //TODO: support scenario outline
            string path = string.Format("Feature:{0}/Scenario:{1}", Escape(fileScope.HeaderBlock.Title), Escape(currentScenario.Title));
            return RunTests(projectItem.ContainingProject, "testpath:" + path, debug);
        }
예제 #9
0
        private IScenarioBlock GetCurrentScenario(GherkinLanguageService languageService, int currentLine, out IGherkinFileScope fileScope)
        {
            fileScope = languageService.GetFileScope();
            if (fileScope == null)
                return null;

            var block = fileScope.GetStepBlockFromStepPosition(currentLine) as IScenarioBlock;
            if (block != null && currentLine > block.KeywordLine + block.BlockRelativeContentEndLine)
                return null; // between two scenarios

            return block;
        }
예제 #10
0
        private IScenarioBlock GetCurrentScenario(GherkinLanguageService languageService, Document activeDocument, out IGherkinFileScope fileScope)
        {
            var currentTextDocument = ((TextDocument)activeDocument.Object("TextDocument"));
            var currentLine = currentTextDocument.Selection.ActivePoint.Line;

            fileScope = languageService.GetFileScope();
            if (fileScope == null)
                return null;

            var block = fileScope.GetStepBlockFromStepPosition(currentLine) as IScenarioBlock;
            if (block != null && currentLine > block.KeywordLine + block.BlockRelativeContentEndLine)
                return null; // between two scenarios

            return block;
        }
        public GherkinFileScopeChange Parse(GherkinTextBufferChange change, IGherkinFileScope previousScope = null)
        {
            var gherkinDialect = GetGherkinDialect(change.ResultTextSnapshot);
            if (gherkinDialect == null)
                return GetInvalidDialectScopeChange(change);

            bool fullParse = false;
            if (previousScope == null)
                fullParse = true;
            else if (!Equals(previousScope.GherkinDialect, gherkinDialect))
                fullParse = true;
            else if (partialParseCount >= PartialParseCountLimit)
                fullParse = true;
            else if (GetFirstAffectedScenario(change, previousScope) == null)
                fullParse = true;

            if (fullParse)
                return FullParse(change.ResultTextSnapshot, gherkinDialect);

            return PartialParse(change, previousScope);
        }
        private string GetFeatureTitle(IGherkinFileScope fileScope)
        {
            if (fileScope.HeaderBlock == null || string.IsNullOrWhiteSpace(fileScope.HeaderBlock.Title))
                return "Unknown";

            return fileScope.HeaderBlock.Title;
        }
예제 #13
0
 public static int TotalErrorCount(this IGherkinFileScope gherkinFileScope)
 {
     return(gherkinFileScope.GetAllBlocks().Sum(block => block.Errors.Count()));
 }
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, ScenarioOutlineExamplesRow examplesRow, IGherkinFileScope fileScope, bool debug)
        {
            if (fileScope.HeaderBlock == null)
            {
                return(false);
            }

            //TODO: support scenario outline
            string path = string.Format("Feature:{0}/Scenario:{1}", Escape(fileScope.HeaderBlock.Title), Escape(currentScenario.Title));

            return(RunTests(projectItem.ContainingProject, "testpath:" + path, debug));
        }
예제 #15
0
 public static IStepBlock GetStepBlockFromStepPosition(this IGherkinFileScope gherkinFileScope, int lineNumber)
 {
     return(gherkinFileScope.GetAllBlocks().LastOrDefault(si => si.KeywordLine < lineNumber) as IStepBlock);
 }
예제 #16
0
 public static IScenarioBlock GetScenarioBlockFromPosition(this IGherkinFileScope gherkinFileScope, int lineNumber)
 {
     return(gherkinFileScope.GetAllBlocks().FirstOrDefault(si => si.KeywordLine <= lineNumber && si.KeywordLine + si.BlockRelativeContentEndLine >= lineNumber) as IScenarioBlock);
 }
        private IScenarioBlock GetFirstAffectedScenario(GherkinTextBufferChange change, IGherkinFileScope previousScope)
        {
            if (change.Type == GherkinTextBufferChangeType.SingleLine)
            {
                //single-line changes on the start cannot influence the previous scenario
                return(previousScope.ScenarioBlocks.LastOrDefault(s => s.GetStartLine() <= change.StartLine));
            }

            // if multiple lines are added at the first line of a block, it can happen that these lines will belong
            // to the previous block
            return(previousScope.ScenarioBlocks.LastOrDefault(s => s.GetStartLine() < change.StartLine));
        }
예제 #18
0
        public static GherkinStep GetStepAtPosition(this IGherkinFileScope gherkinFileScope, int lineNumber)
        {
            IStepBlock block;

            return(GetStepAtPosition(gherkinFileScope, lineNumber, out block));
        }
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, ScenarioOutlineExamplesRow examplesRow, IGherkinFileScope fileScope, bool debug)
        {
            if (fileScope.HeaderBlock == null)
            {
                return(false);
            }

            string escapedFeatureTitle = Escape(fileScope.HeaderBlock.Title);
            string scenarioPattern     = currentScenario is IScenarioOutlineBlock
                                   ? string.Format("{0}, *", currentScenario.Title)
                                   : currentScenario.Title;

            string path = string.Format("Feature:{0}/Scenario:{1}", escapedFeatureTitle, Escape(scenarioPattern));

            return(RunTests(projectItem.ContainingProject, string.Format("testpath:{0}", path), debug));
        }
예제 #20
0
 public static IEnumerable <GherkinStep> GetAllStepsWithFirstExampleSubstituted(this IGherkinFileScope gherkinFileScope)
 {
     return(gherkinFileScope.GetAllBlocks().OfType <IStepBlock>().SelectMany(b => b is IScenarioOutlineBlock ? GetSubstitutedSteps((IScenarioOutlineBlock)b) : b.Steps));
 }
 private IEnumerable<StepInstance> GetUnboundSteps(IStepDefinitionMatchService bindingMatchService, IGherkinFileScope fileScope, CultureInfo bindingCulture)
 {
     return fileScope.GetAllStepsWithFirstExampleSubstituted().Where(s => IsListed(s, bindingMatchService, bindingCulture));
 }
 public GherkinTextBufferPartialParserListener(GherkinDialect gherkinDialect, ITextSnapshot textSnapshot, IProjectScope projectScope, IGherkinFileScope previousScope, int changeLastLine, int changeLineDelta)
     : base(gherkinDialect, textSnapshot, projectScope)
 {
     this.previousScope   = previousScope;
     this.changeLastLine  = changeLastLine;
     this.changeLineDelta = changeLineDelta;
 }
예제 #23
0
        private IScenarioBlock GetCurrentScenario(GherkinLanguageService languageService, int currentLine, out IGherkinFileScope fileScope)
        {
            fileScope = languageService.GetFileScope();
            if (fileScope == null)
            {
                return(null);
            }

            var block = fileScope.GetStepBlockFromStepPosition(currentLine) as IScenarioBlock;

            if (block != null && currentLine > block.KeywordLine + block.BlockRelativeContentEndLine)
            {
                return(null); // between two scenarios
            }
            return(block);
        }
예제 #24
0
 public void Dispose()
 {
     visualStudioTracer.Trace("Language service disposed", "GherkinLanguageService");
     isDisposed = true;
     projectScope.GherkinDialectServicesChanged -= GherkinDialectServicesChanged;
     lastGherkinFileScope = null;
 }
예제 #25
0
 private void RegisterScopeChange(GherkinFileScopeChange scopeChange)
 {
     lastGherkinFileScope = scopeChange.GherkinFileScope;
     TriggerScopeChange(scopeChange);
 }
예제 #26
0
        private IScenarioBlock GetCurrentScenario(GherkinLanguageService languageService, int currentLine, out IGherkinFileScope fileScope)
        {
            fileScope = languageService.GetFileScope();
            if (fileScope == null)
            {
                return(null);
            }

            return(fileScope.GetScenarioBlockFromPosition(currentLine));
        }
예제 #27
0
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope, bool debug)
        {
            int sourceLine = currentScenario.KeywordLine + 1; // keywordline is zero-indexed

            return(RunFromCodeBehind(projectItem, codeBehindTextDocument => GetCodeBehindLine(codeBehindTextDocument, sourceLine), debug));
        }
        private GherkinFileScopeChange MergePartialResult(IGherkinFileScope previousScope, IGherkinFileScope partialResult, IScenarioBlock firstAffectedScenario, IScenarioBlock firstUnchangedScenario, int lineCountDelta)
        {
            Debug.Assert(partialResult.HeaderBlock == null, "Partial parse cannot re-parse header");
            Debug.Assert(partialResult.BackgroundBlock == null, "Partial parse cannot re-parse background");

            var changedBlocks = new List <IGherkinFileBlock>();
            var shiftedBlocks = new List <IGherkinFileBlock>();

            var fileScope = new GherkinFileScope(previousScope.GherkinDialect, partialResult.TextSnapshot)
            {
                HeaderBlock     = previousScope.HeaderBlock,
                BackgroundBlock = previousScope.BackgroundBlock
            };

            // inserting the non-affected scenarios
            fileScope.ScenarioBlocks.AddRange(previousScope.ScenarioBlocks.TakeUntilItemExclusive(firstAffectedScenario));

            //inserting partial result
            fileScope.ScenarioBlocks.AddRange(partialResult.ScenarioBlocks);
            changedBlocks.AddRange(partialResult.ScenarioBlocks);
            if (partialResult.InvalidFileEndingBlock != null)
            {
                VisualStudioTracer.Assert(firstUnchangedScenario == null, "first affected scenario is not null");
                // the last scenario was changed, but it became invalid
                fileScope.InvalidFileEndingBlock = partialResult.InvalidFileEndingBlock;
                changedBlocks.Add(fileScope.InvalidFileEndingBlock);
            }

            if (firstUnchangedScenario != null)
            {
                VisualStudioTracer.Assert(partialResult.InvalidFileEndingBlock == null, "there is an invalid file ending block");

                // inserting the non-effected scenarios at the end
                var shiftedScenarioBlocks = previousScope.ScenarioBlocks.SkipFromItemInclusive(firstUnchangedScenario)
                                            .Select(scenario => scenario.Shift(lineCountDelta)).ToArray();
                fileScope.ScenarioBlocks.AddRange(shiftedScenarioBlocks);
                shiftedBlocks.AddRange(shiftedScenarioBlocks);

                if (previousScope.InvalidFileEndingBlock != null)
                {
                    fileScope.InvalidFileEndingBlock = previousScope.InvalidFileEndingBlock.Shift(lineCountDelta);
                    shiftedBlocks.Add(fileScope.InvalidFileEndingBlock);
                }
            }

            return(new GherkinFileScopeChange(fileScope, false, false, changedBlocks, shiftedBlocks));
        }
예제 #29
0
 public void Dispose()
 {
     visualStudioTracer.Trace("Language service disposed", "GherkinLanguageService");
     isDisposed = true;
     projectScope.GherkinDialectServicesChanged -= ReParseEntireFile;
     if (enableStepMatchColoring)
     {
         projectScope.StepSuggestionProvider.Ready -= ReParseEntireFile;
         projectScope.StepSuggestionProvider.BindingsChanged -= ReParseEntireFile;
     }
     lastGherkinFileScope = null;
 }
예제 #30
0
 public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope,
                         bool debug)
 {
     return RunInCurrentContext(VsxHelper.GetFileName(projectItem), debug, currentScenario.KeywordLine);
 }
        private IScenarioBlock GetFirstAffectedScenario(GherkinTextBufferChange change, IGherkinFileScope previousScope)
        {
            if (change.Type == GherkinTextBufferChangeType.SingleLine)
                //single-line changes on the start cannot influence the previous scenario
                return previousScope.ScenarioBlocks.LastOrDefault(s => s.GetStartLine() <= change.StartLine);

            // if multiple lines are added at the first line of a block, it can happen that these lines will belong
            // to the previous block
            return previousScope.ScenarioBlocks.LastOrDefault(s => s.GetStartLine() < change.StartLine); 
        }
예제 #32
0
        public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope, bool debug)
        {
            var testRunnerGateway = GetCurrentTestRunnerGateway(projectItem.ContainingProject);

            if (testRunnerGateway == null)
            {
                return(false);
            }

            return(testRunnerGateway.RunScenario(projectItem, currentScenario, fileScope, debug));
        }
예제 #33
0
 public static IEnumerable <GherkinStep> GetAllSteps(this IGherkinFileScope gherkinFileScope)
 {
     return(gherkinFileScope.GetAllBlocks().OfType <IStepBlock>().SelectMany(b => b.Steps));
 }
예제 #34
0
 private void RegisterScopeChange(GherkinFileScopeChange scopeChange)
 {
     lastGherkinFileScope = scopeChange.GherkinFileScope;
     TriggerScopeChange(scopeChange);
 }
 private IEnumerable <StepInstance> GetUnboundSteps(IStepDefinitionMatchService bindingMatchService, IGherkinFileScope fileScope, CultureInfo bindingCulture)
 {
     return(fileScope.GetAllStepsWithFirstExampleSubstituted().Where(s => IsListed(s, bindingMatchService, bindingCulture)));
 }
        private GherkinFileScopeChange PartialParse(GherkinTextBufferChange change, IGherkinFileScope previousScope)
        {
            visualStudioTracer.Trace("Start incremental parsing", ParserTraceCategory);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            partialParseCount++;

            var textSnapshot = change.ResultTextSnapshot;

            IScenarioBlock firstAffectedScenario = GetFirstAffectedScenario(change, previousScope);
            Debug.Assert(firstAffectedScenario != null);
            int parseStartPosition = textSnapshot.GetLineFromLineNumber(firstAffectedScenario.GetStartLine()).Start;

            string fileContent = textSnapshot.GetText(parseStartPosition, textSnapshot.Length - parseStartPosition);

            var gherkinListener = new GherkinTextBufferPartialParserListener(
                previousScope.GherkinDialect,
                textSnapshot, projectScope.Classifications, 
                previousScope, 
                change.EndLine, change.LineCountDelta);

            var scanner = new GherkinScanner(previousScope.GherkinDialect, fileContent, firstAffectedScenario.GetStartLine());

            IScenarioBlock firstUnchangedScenario = null;
            try
            {
                scanner.Scan(gherkinListener);
            }
            catch (PartialListeningDoneException partialListeningDoneException)
            {
                firstUnchangedScenario = partialListeningDoneException.FirstUnchangedScenario;
            }

            var partialResult = gherkinListener.GetResult();

            var result = MergePartialResult(previousScope, partialResult, firstAffectedScenario, firstUnchangedScenario, change.LineCountDelta);
            stopwatch.Stop();
            TraceFinishParse(stopwatch, "incremental", result);
            return result;
        }
예제 #37
0
 internal static GherkinFileScopeChange CreateEntireScopeChange(IGherkinFileScope fileScope)
 {
     return new GherkinFileScopeChange(fileScope, true, true, fileScope.GetAllBlocks(), Enumerable.Empty<IGherkinFileBlock>());
 }
        private GherkinFileScopeChange MergePartialResult(IGherkinFileScope previousScope, IGherkinFileScope partialResult, IScenarioBlock firstAffectedScenario, IScenarioBlock firstUnchangedScenario, int lineCountDelta)
        {
            Debug.Assert(partialResult.HeaderBlock == null, "Partial parse cannot re-parse header");
            Debug.Assert(partialResult.BackgroundBlock == null, "Partial parse cannot re-parse background");

            List<IGherkinFileBlock> changedBlocks = new List<IGherkinFileBlock>();
            List<IGherkinFileBlock> shiftedBlocks = new List<IGherkinFileBlock>();

            GherkinFileScope fileScope = new GherkinFileScope(previousScope.GherkinDialect, partialResult.TextSnapshot)
                                             {
                                                 HeaderBlock = previousScope.HeaderBlock,
                                                 BackgroundBlock = previousScope.BackgroundBlock
                                             };

            // inserting the non-affected scenarios
            fileScope.ScenarioBlocks.AddRange(previousScope.ScenarioBlocks.TakeUntilItemExclusive(firstAffectedScenario));

            //inserting partial result
            fileScope.ScenarioBlocks.AddRange(partialResult.ScenarioBlocks);
            changedBlocks.AddRange(partialResult.ScenarioBlocks);
            if (partialResult.InvalidFileEndingBlock != null)
            {
                Debug.Assert(firstUnchangedScenario == null);
                // the last scenario was changed, but it became invalid
                fileScope.InvalidFileEndingBlock = partialResult.InvalidFileEndingBlock;
                changedBlocks.Add(fileScope.InvalidFileEndingBlock);
            }

            if (firstUnchangedScenario != null)
            {
                Debug.Assert(partialResult.InvalidFileEndingBlock == null);

                // inserting the non-effected scenarios at the end
                var shiftedScenarioBlocks = previousScope.ScenarioBlocks.SkipFromItemInclusive(firstUnchangedScenario)
                    .Select(scenario => scenario.Shift(lineCountDelta)).ToArray();
                fileScope.ScenarioBlocks.AddRange(shiftedScenarioBlocks);
                shiftedBlocks.AddRange(shiftedScenarioBlocks);

                if (previousScope.InvalidFileEndingBlock != null)
                {
                    fileScope.InvalidFileEndingBlock = previousScope.InvalidFileEndingBlock.Shift(lineCountDelta);
                    shiftedBlocks.Add(fileScope.InvalidFileEndingBlock);
                }
            }

            return new GherkinFileScopeChange(fileScope, false, false, changedBlocks, shiftedBlocks);
        }
예제 #39
0
        private IScenarioBlock GetCurrentScenario(GherkinLanguageService languageService, Document activeDocument, out IGherkinFileScope fileScope)
        {
            var currentTextDocument = ((TextDocument)activeDocument.Object("TextDocument"));
            var currentLine         = currentTextDocument.Selection.ActivePoint.Line;

            fileScope = languageService.GetFileScope();
            if (fileScope == null)
            {
                return(null);
            }

            var block = fileScope.GetStepBlockFromStepPosition(currentLine) as IScenarioBlock;

            if (block != null && currentLine > block.KeywordLine + block.BlockRelativeContentEndLine)
            {
                return(null); // between two scenarios
            }
            return(block);
        }
 public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope, bool debug)
 {
     int sourceLine = currentScenario.KeywordLine + 1; // keywordline is zero-indexed
     return RunFromCodeBehind(projectItem, codeBehindTextDocument => GetCodeBehindLine(codeBehindTextDocument, sourceLine), debug);
 }
예제 #41
0
 public bool RunScenario(ProjectItem projectItem, IScenarioBlock currentScenario, IGherkinFileScope fileScope, bool debug)
 {
     return(RunInCurrentContext(VsxHelper.GetFileName(projectItem), debug, currentScenario.KeywordLine));
 }