From 684d8706d4fe7f58e712ee008b4a5292a73613ec Mon Sep 17 00:00:00 2001 From: Srikanth Date: Tue, 7 May 2024 21:29:57 +0530 Subject: [PATCH] add support to print list of implemented steps (#2433) * add support to print list of implemented steps usage: gauge list --steps Signed-off-by: sriv * bump version -> 1.5.7 Signed-off-by: sriv * fix linter error for errcheck Signed-off-by: sriv --------- Signed-off-by: sriv --- cmd/list.go | 46 +++++++++++++++++++++++++++++++++--- cmd/list_test.go | 28 ++++++++++++++++++++++ cmd/mockRunner.go | 50 ++++++++++++++++++++++++++++++++++++++++ filter/specItemFilter.go | 3 ++- version/version.go | 2 +- 5 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 cmd/mockRunner.go diff --git a/cmd/list.go b/cmd/list.go index fffe19da0..75882c1fd 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -10,7 +10,11 @@ import ( "fmt" supersort "sort" + gm "github.com/getgauge/gauge-proto/go/gauge_messages" "github.com/getgauge/gauge/config" + "github.com/getgauge/gauge/manifest" + "github.com/getgauge/gauge/runner" + "github.com/getgauge/gauge/util" "github.com/getgauge/gauge/filter" "github.com/getgauge/gauge/gauge" @@ -22,8 +26,8 @@ import ( var ( listCmd = &cobra.Command{ Use: "list [flags] [args]", - Short: "List specifications, scenarios or tags for a gauge project", - Long: `List specifications, scenarios or tags for a gauge project`, + Short: "List specifications, scenarios, steps or tags for a gauge project", + Long: `List specifications, scenarios, steps or tags for a gauge project`, Example: ` gauge list --tags specs`, Run: func(cmd *cobra.Command, args []string) { if err := config.SetProjectRoot(args); err != nil { @@ -46,7 +50,11 @@ var ( logger.Info(true, "[Tags]") listTags(specs, print) } - if !specsFlag && !scenariosFlag && !tagsFlag { + if stepsFlag { + logger.Info(true, "[Steps]") + listSteps(specs, print) + } + if !specsFlag && !scenariosFlag && !tagsFlag && !stepsFlag { exit(fmt.Errorf("Missing flag, nothing to list"), cmd.UsageString()) } }, @@ -55,6 +63,7 @@ var ( tagsFlag bool specsFlag bool scenariosFlag bool + stepsFlag bool ) func init() { @@ -62,6 +71,7 @@ func init() { listCmd.Flags().BoolVarP(&tagsFlag, "tags", "", false, "List the tags in projects") listCmd.Flags().BoolVarP(&specsFlag, "specs", "", false, "List the specifications in projects") listCmd.Flags().BoolVarP(&scenariosFlag, "scenarios", "", false, "List the scenarios in projects") + listCmd.Flags().BoolVarP(&stepsFlag, "steps", "", false, "List all the steps in projects (including concept steps). Does not include unused steps.") } type handleResult func([]string) @@ -96,6 +106,10 @@ func listSpecifications(s []*gauge.Specification, f handleResult) { f(sortedDistinctElements(allSpecs)) } +func listSteps(s []*gauge.Specification, f handleResult) { + f(sortedDistinctElements(getImplementedStepsWithAliases())) +} + func sortedDistinctElements(s []string) []string { unique := uniqueNonEmptyElementsOf(s) supersort.Strings(unique) @@ -120,5 +134,31 @@ func uniqueNonEmptyElementsOf(input []string) []string { } return us +} + +func getImplementedStepsWithAliases() []string { + r, err := connectToRunner() + defer func() { _ = r.Kill() }() + if err != nil { + panic(err) + } + getAllStepsRequest := &gm.Message{MessageType: gm.Message_StepNamesRequest, StepNamesRequest: &gm.StepNamesRequest{}} + response, err := r.ExecuteMessageWithTimeout(getAllStepsRequest) + if err != nil { + exit(fmt.Errorf("error while connecting to runner : %s", err.Error()), "unable to get steps from runner") + } + return response.GetStepNamesResponse().GetSteps() +} + +var connectToRunner = func() (runner.Runner, error) { + outFile, err := util.OpenFile(logger.ActiveLogFile) + if err != nil { + return nil, err + } + manifest, err := manifest.ProjectManifest() + if err != nil { + return nil, err + } + return runner.StartGrpcRunner(manifest, outFile, outFile, config.IdeRequestTimeout(), false) } diff --git a/cmd/list_test.go b/cmd/list_test.go index a87ea434c..c9c73e11c 100644 --- a/cmd/list_test.go +++ b/cmd/list_test.go @@ -10,7 +10,9 @@ import ( "reflect" "testing" + "github.com/getgauge/gauge-proto/go/gauge_messages" "github.com/getgauge/gauge/gauge" + "github.com/getgauge/gauge/runner" ) func TestOnlyUniqueTagsAreReturned(t *testing.T) { @@ -35,6 +37,32 @@ func TestOnlyUniqueSceanriosAreReturned(t *testing.T) { }) } +func TestOnlyUniqueStepsAreReturned(t *testing.T) { + connectToRunner = func() (runner.Runner, error) { + return &mockRunner{ + response: &gauge_messages.Message{ + StepNamesResponse: &gauge_messages.StepNamesResponse{ + Steps: []string{ + "Vowels are .", + "Vowels in English language are .", + "The word has vowels.", + "Almost all words have vowels ", + }, + }, + }, + }, nil + } + expected := []string{ + "Almost all words have vowels ", + "The word has vowels.", + "Vowels are .", + "Vowels in English language are .", + } + listSteps([]*gauge.Specification{buildTestSpecification()}, func(res []string) { + verifyUniqueness(res, expected, t) + }) +} + func buildTestSpecification() *gauge.Specification { return &gauge.Specification{ Heading: &gauge.Heading{ diff --git a/cmd/mockRunner.go b/cmd/mockRunner.go new file mode 100644 index 000000000..24dbb3d66 --- /dev/null +++ b/cmd/mockRunner.go @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------- + * Copyright (c) ThoughtWorks, Inc. + * Licensed under the Apache License, Version 2.0 + * See LICENSE in the project root for license information. + *----------------------------------------------------------------*/ + +package cmd + +import ( + "net" + + "github.com/getgauge/gauge-proto/go/gauge_messages" + "github.com/getgauge/gauge/runner" +) + +type mockRunner struct { + response *gauge_messages.Message +} + +func (r *mockRunner) ExecuteAndGetStatus(m *gauge_messages.Message) *gauge_messages.ProtoExecutionResult { + return nil +} + +func (r *mockRunner) ExecuteMessageWithTimeout(m *gauge_messages.Message) (*gauge_messages.Message, error) { + return r.response, nil +} + +func (r *mockRunner) Alive() bool { + return true +} + +func (r *mockRunner) Kill() error { + return nil +} + +func (r *mockRunner) Connection() net.Conn { + return nil +} + +func (r *mockRunner) IsMultithreaded() bool { + return false +} + +func (r *mockRunner) Info() *runner.RunnerInfo { + return &runner.RunnerInfo{Killed: false} +} + +func (r *mockRunner) Pid() int { + return 0 +} diff --git a/filter/specItemFilter.go b/filter/specItemFilter.go index 133bdc7b7..7ce41d151 100644 --- a/filter/specItemFilter.go +++ b/filter/specItemFilter.go @@ -8,7 +8,6 @@ package filter import ( "errors" - "github.com/getgauge/gauge/env" "go/constant" "go/token" "go/types" @@ -16,6 +15,8 @@ import ( "strconv" "strings" + "github.com/getgauge/gauge/env" + "fmt" "github.com/getgauge/gauge/gauge" diff --git a/version/version.go b/version/version.go index 125aac1b5..370ef02e9 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ import ( ) // CurrentGaugeVersion represents the current version of Gauge -var CurrentGaugeVersion = &Version{1, 6, 6} +var CurrentGaugeVersion = &Version{1, 6, 7} // BuildMetadata represents build information of current release (e.g, nightly build information) var BuildMetadata = ""