Skip to content

Commit

Permalink
Merge branch 'gauge_docs'
Browse files Browse the repository at this point in the history
  • Loading branch information
Apoorva-GA committed Oct 23, 2017
2 parents bf8f3a4 + 38eeb23 commit c96bdbb
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 2 deletions.
2 changes: 2 additions & 0 deletions conceptExtractor/conceptExtractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type extractor struct {
errors []error
}

// ExtractConcept creates concept form the selected text and writes the concept to the given concept file.
func ExtractConcept(conceptName *gauge_messages.Step, steps []*gauge_messages.Step, conceptFileName string, changeAcrossProject bool, selectedTextInfo *gauge_messages.TextInfo) (bool, error, []string) {
content := SPEC_HEADING_TEMPLATE
if util.IsSpec(selectedTextInfo.GetFileName()) {
Expand All @@ -63,6 +64,7 @@ func ExtractConcept(conceptName *gauge_messages.Step, steps []*gauge_messages.St
return true, errors.New(""), []string{conceptFileName, selectedTextInfo.GetFileName()}
}

// ReplaceExtractedStepsWithConcept replaces the steps selected for concept extraction with the concept name given.
func ReplaceExtractedStepsWithConcept(selectedTextInfo *gauge_messages.TextInfo, conceptText string) string {
content, _ := common.ReadFileContents(selectedTextInfo.GetFileName())
return replaceText(content, selectedTextInfo, conceptText)
Expand Down
2 changes: 2 additions & 0 deletions execution/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type ExecutionEvent struct {
ExecutionInfo gauge_messages.ExecutionInfo
}

// NewExecutionEvent creates a new execution event.
func NewExecutionEvent(t Topic, i gauge.Item, r result.Result, stream int, executionInfo gauge_messages.ExecutionInfo) ExecutionEvent {
return ExecutionEvent{
Topic: t,
Expand Down Expand Up @@ -61,6 +62,7 @@ const (

var subscriberRegistry map[Topic][]chan ExecutionEvent

// InitRegistry is used for console reporting, execution API and rerun of specs
func InitRegistry() {
subscriberRegistry = make(map[Topic][]chan ExecutionEvent, 0)
subscriberRegistry[SuiteStart] = make([]chan ExecutionEvent, 0)
Expand Down
20 changes: 20 additions & 0 deletions execution/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@
// You should have received a copy of the GNU General Public License
// along with Gauge. If not, see <http://www.gnu.org/licenses/>.

/*
Execution can be of two types
- Simple execution
- Paralell execution
Execution Flow :
- Checks for updates
- Validation
- Init Registry
- Saving Execution result
Strategy
- Lazy : Lazy is a parallelization strategy for execution. In this case tests assignment will be dynamic during execution, i.e. assign the next spec in line to the stream that has completed it’s previous execution and is waiting for more work.
- Eager : Eager is a parallelization strategy for execution. In this case tests are distributed before execution, thus making them an equal number based distribution.
*/
package execution

import (
Expand Down Expand Up @@ -49,7 +64,10 @@ import (
"github.com/getgauge/gauge/validation"
)

// NumberOfExecutionStreams shows the number of execution streams, in parallel execution.
var NumberOfExecutionStreams int

// InParallel if true executes the specs in parallel else in serial.
var InParallel bool

type suiteExecutor interface {
Expand Down Expand Up @@ -88,6 +106,8 @@ func newExecutionInfo(s *gauge.SpecCollection, r runner.Runner, ph plugin.Handle
}
}

// ExecuteSpecs : Check for updates, validates the specs (by invoking the respective language runners), initiates the registry which is needed for console reporting, execution API and Rerunning of specs
// and finally saves the execution result as binary in .gauge folder.
func ExecuteSpecs(specDirs []string) int {
err := validateFlags()
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions execution/parallelExecution.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ import (

var Strategy string

// Eager is a parallelization strategy for execution. In this case tests are distributed before execution, thus making them an equal number based distribution.
const Eager string = "eager"

// Lazy is a parallelization strategy for execution. In this case tests assignment will be dynamic during execution, i.e. assign the next spec in line to the stream that has completed it’s previous execution and is waiting for more work.
const Lazy string = "lazy"
const enableMultithreadingEnv = "enable_multithreading"

Expand Down
3 changes: 3 additions & 0 deletions execution/result/scenarioResult.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ func NewScenarioResult(sce *gauge_messages.ProtoScenario) *ScenarioResult {
return &ScenarioResult{ProtoScenario: sce}
}

// SetFailure sets the scenarioResult as failed
func (s *ScenarioResult) SetFailure() {
s.ProtoScenario.ExecutionStatus = gauge_messages.ExecutionStatus_FAILED
s.ProtoScenario.Failed = true
}

// GetFailed returns the state of the scenario result
func (s *ScenarioResult) GetFailed() bool {
return s.ProtoScenario.GetExecutionStatus() == gauge_messages.ExecutionStatus_FAILED
}
Expand All @@ -58,6 +60,7 @@ func (s *ScenarioResult) AddExecTime(execTime int64) {
s.ProtoScenario.ExecutionTime = currentScenarioExecTime + execTime
}

// ExecTime returns the time taken for scenario execution
func (s *ScenarioResult) ExecTime() int64 {
return s.ProtoScenario.ExecutionTime
}
Expand Down
5 changes: 5 additions & 0 deletions execution/result/specResult.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/getgauge/gauge/gauge_messages"
)

// SpecResult represents the result of spec execution
type SpecResult struct {
ProtoSpec *gauge_messages.ProtoSpec
ScenarioFailedCount int
Expand All @@ -33,6 +34,7 @@ type SpecResult struct {
Errors []*gauge_messages.Error
}

// SetFailure sets the result to failed
func (specResult *SpecResult) SetFailure() {
specResult.IsFailed = true
}
Expand All @@ -45,6 +47,7 @@ func (specResult *SpecResult) AddSpecItems(resolvedItems []*gauge_messages.Proto
specResult.ProtoSpec.Items = append(specResult.ProtoSpec.Items, resolvedItems...)
}

// AddScenarioResults adds the scenario result to the spec result.
func (specResult *SpecResult) AddScenarioResults(scenarioResults []Result) {
for _, scenarioResult := range scenarioResults {
if scenarioResult.GetFailed() {
Expand All @@ -57,6 +60,7 @@ func (specResult *SpecResult) AddScenarioResults(scenarioResults []Result) {
specResult.ScenarioCount += len(scenarioResults)
}

// AddTableRelatedScenarioResult aggregates the data table driven spec results.
func (specResult *SpecResult) AddTableRelatedScenarioResult(scenarioResults [][]Result, index int) {
numberOfScenarios := len(scenarioResults[0])

Expand Down Expand Up @@ -106,6 +110,7 @@ func (specResult *SpecResult) ExecTime() int64 {
return specResult.ExecutionTime
}

// GetFailed returns the state of the result
func (specResult *SpecResult) GetFailed() bool {
return specResult.IsFailed
}
Expand Down
9 changes: 9 additions & 0 deletions execution/result/suiteResult.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/getgauge/gauge/gauge_messages"
)

// SuitResult represents the result of suit execution
type SuiteResult struct {
SpecResults []*SpecResult
PreSuite *(gauge_messages.ProtoHookFailure)
Expand All @@ -41,6 +42,7 @@ type SuiteResult struct {
SpecsSkippedCount int
}

// NewSuiteResult is a constructor for SuitResult
func NewSuiteResult(tags string, startTime time.Time) *SuiteResult {
result := new(SuiteResult)
result.SpecResults = make([]*SpecResult, 0)
Expand All @@ -51,10 +53,12 @@ func NewSuiteResult(tags string, startTime time.Time) *SuiteResult {
return result
}

// SetFailure sets the result to failed
func (sr *SuiteResult) SetFailure() {
sr.IsFailed = true
}

// SetSpecsSkippedCount sets the count of specs skipped.
func (sr *SuiteResult) SetSpecsSkippedCount() {
sr.SpecsSkippedCount = 0
for _, specRes := range sr.SpecResults {
Expand All @@ -64,6 +68,7 @@ func (sr *SuiteResult) SetSpecsSkippedCount() {
}
}

// AddUnhandledError adds the unhandled error to suit result.
func (sr *SuiteResult) AddUnhandledError(err error) {
sr.UnhandledErrors = append(sr.UnhandledErrors, err)
}
Expand All @@ -72,6 +77,7 @@ func (sr *SuiteResult) UpdateExecTime(startTime time.Time) {
sr.ExecutionTime = int64(time.Since(startTime) / 1e6)
}

// AddSpecResult adds a specs result to suit result.
func (sr *SuiteResult) AddSpecResult(specResult *SpecResult) {
if specResult.IsFailed {
sr.IsFailed = true
Expand All @@ -81,6 +87,7 @@ func (sr *SuiteResult) AddSpecResult(specResult *SpecResult) {
sr.SpecResults = append(sr.SpecResults, specResult)
}

// AddSpecResults adds multiple spec results to suit result.
func (sr *SuiteResult) AddSpecResults(specResults []*SpecResult) {
for _, result := range specResults {
sr.AddSpecResult(result)
Expand Down Expand Up @@ -109,10 +116,12 @@ func (sr *SuiteResult) AddPostHook(f ...*gauge_messages.ProtoHookFailure) {
sr.PostSuite = f[0]
}

// ExecTime returns the time taken to execute the suit
func (sr *SuiteResult) ExecTime() int64 {
return sr.ExecutionTime
}

// GetFailed returns the state of the result
func (sr *SuiteResult) GetFailed() bool {
return sr.IsFailed
}
Expand Down
6 changes: 5 additions & 1 deletion parser/conceptParser.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ type ConceptParser struct {
currentConcept *gauge.Step
}

//concept file can have multiple concept headings
// concept file can have multiple concept headings.
// Generates token for the given concept file and cretes concepts(array of steps) and parse results.
func (parser *ConceptParser) Parse(text, fileName string) ([]*gauge.Step, *ParseResult) {
defer parser.resetState()

Expand All @@ -44,6 +45,7 @@ func (parser *ConceptParser) Parse(text, fileName string) ([]*gauge.Step, *Parse
return concepts, &ParseResult{ParseErrors: append(errs, res.ParseErrors...), Warnings: res.Warnings}
}

// Reads file contents from a give file and parses the file.
func (parser *ConceptParser) ParseFile(file string) ([]*gauge.Step, *ParseResult) {
fileText, fileReadErr := common.ReadFileContents(file)
if fileReadErr != nil {
Expand Down Expand Up @@ -214,6 +216,7 @@ func (parser *ConceptParser) createConceptLookup(concept *gauge.Step) {
}
}

// CreateConceptsDictionary generates a ConceptDictionary which is map of concept text to concept. ConceptDictionary is used to search for a concept.
func CreateConceptsDictionary() (*gauge.ConceptDictionary, *ParseResult) {
cptFilesMap := make(map[string]bool, 0)
for _, cpt := range util.GetConceptFiles() {
Expand Down Expand Up @@ -249,6 +252,7 @@ func AddConcept(concepts []*gauge.Step, file string, conceptDictionary *gauge.Co
return mergeDuplicateConceptErrors(duplicateConcepts)
}

// AddConcepts parses the given concept file and adds each concept to the concept dictionary.
func AddConcepts(conceptFiles []string, conceptDictionary *gauge.ConceptDictionary) ([]*gauge.Step, []ParseError) {
var conceptSteps []*gauge.Step
var parseResults []*ParseResult
Expand Down
3 changes: 2 additions & 1 deletion parser/dataTableSpecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package parser

import "github.com/getgauge/gauge/gauge"

// Creates a spec for each data table row
// GetSpecsForDataTableRows creates a spec for each data table row
func GetSpecsForDataTableRows(s []*gauge.Specification, errMap *gauge.BuildErrors) (specs []*gauge.Specification) {
for _, spec := range s {
if spec.DataTable.IsInitialized() {
Expand Down Expand Up @@ -106,6 +106,7 @@ func getTableWithOneRow(t gauge.Table, i int) *gauge.Table {
return gauge.NewTable(t.Headers, row, t.LineNo)
}

// FilterTableRelatedScenarios filters Scenarios that are using dynamic params from data table.
func FilterTableRelatedScenarios(scenarios []*gauge.Scenario, fun func(*gauge.Scenario) bool) (otherScenarios, tableRelatedScenarios []*gauge.Scenario) {
for _, scenario := range scenarios {
if fun(scenario) {
Expand Down
1 change: 1 addition & 0 deletions parser/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func arrayContains(array []string, toFind string) bool {
return false
}

// Gives unescaped string.
func GetUnescapedString(string1 string) string {
unescaped := strconv.Quote(string1)
return unescaped[1 : len(unescaped)-1]
Expand Down
24 changes: 24 additions & 0 deletions parser/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@
// You should have received a copy of the GNU General Public License
// along with Gauge. If not, see <http://www.gnu.org/licenses/>.

/*
Parses all the specs in the list of directories given and also de-duplicates all specs passed through `specDirs` before parsing specs.
Gets all the specs files in the given directory and generates token for each spec file.
While parsing a concept file, concepts are inlined i.e. concept in the spec file is replaced with steps that concept has in the concept file.
While creating a specification file parser applies the converter functions.
Parsing a spec file gives a specification with parseresult. ParseResult contains ParseErrors, CriticalErrors, Warnings and FileName
Errors can be generated, While
- Generating tokens
- Applying converters
- After Applying converters
If a parse error is found in a spec, only that spec is ignored and others will continue execution.
This doesn't invoke the language runner.
Eg : Multiple spec headings found in same file.
Scenario should be defined after the spec heading.
Critical error :
Circular reference of concepts - Doesn't parse specs becz it goes in recursion and crashes
*/
package parser

import (
Expand All @@ -32,6 +52,8 @@ import (
)

// TODO: Use single channel instead of one for spec and another for result, so that mapping is consistent
// ParseSpecFiles - gets all the spec files and parse each spec file.
// Generates specifications and parse results.
func ParseSpecFiles(specFiles []string, conceptDictionary *gauge.ConceptDictionary, buildErrors *gauge.BuildErrors) ([]*gauge.Specification, []*ParseResult) {
parseResultsChan := make(chan *ParseResult, len(specFiles))
specsChan := make(chan *gauge.Specification, len(specFiles))
Expand Down Expand Up @@ -59,12 +81,14 @@ func ParseSpecFiles(specFiles []string, conceptDictionary *gauge.ConceptDictiona
return specs, parseResults
}

// ParseSpecs parses specs in the give directory and gives specification and pass/fail status, used in validation.
func ParseSpecs(args []string, conceptsDictionary *gauge.ConceptDictionary, buildErrors *gauge.BuildErrors) ([]*gauge.Specification, bool) {
specs, failed := parseSpecsInDirs(conceptsDictionary, args, buildErrors)
specsToExecute := order.Sort(filter.FilterSpecs(specs))
return specsToExecute, failed
}

// ParseConcepts creates concept dictionary and concept parse result.
func ParseConcepts() (*gauge.ConceptDictionary, *ParseResult) {
conceptsDictionary, conceptParseResult := CreateConceptsDictionary()
HandleParseResult(conceptParseResult)
Expand Down
1 change: 1 addition & 0 deletions parser/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func (invalidSpecialParamError invalidSpecialParamError) Error() string {
return invalidSpecialParamError.message
}

// GetResolvedParams based on the arg type(static, dynamic, table, special_string, special_table) resolves the parameter of a step.
func (paramResolver *ParamResolver) GetResolvedParams(step *gauge.Step, parent *gauge.Step, lookup *gauge.ArgLookup) []*gauge_messages.Parameter {
parameters := make([]*gauge_messages.Parameter, 0)
for _, arg := range step.Args {
Expand Down
7 changes: 7 additions & 0 deletions parser/specparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func (parser *SpecParser) initialize() {
parser.processors[gauge.TearDownKind] = processTearDown
}

// Parse generates tokens for the given spec text and creates the specification.
func (parser *SpecParser) Parse(specText string, conceptDictionary *gauge.ConceptDictionary, specFile string) (*gauge.Specification, *ParseResult) {
tokens, errs := parser.GenerateTokens(specText, specFile)
spec, res := parser.CreateSpecification(tokens, conceptDictionary, specFile)
Expand All @@ -89,6 +90,7 @@ func (parser *SpecParser) ParseSpecText(specText string, specFile string) (*gaug
return spec, res
}

// Generates tokens based on the parsed line.
func (parser *SpecParser) GenerateTokens(specText, fileName string) ([]*Token, []ParseError) {
parser.initialize()
parser.scanner = bufio.NewScanner(strings.NewReader(specText))
Expand Down Expand Up @@ -250,6 +252,7 @@ func (parser *SpecParser) clearState() {
parser.currentState = 0
}

// CreateSpecification creates specification from the given set of tokens.
func (parser *SpecParser) CreateSpecification(tokens []*Token, conceptDictionary *gauge.ConceptDictionary, specFile string) (*gauge.Specification, *ParseResult) {
parser.conceptDictionary = conceptDictionary
specification, finalResult := parser.createSpecification(tokens, specFile)
Expand Down Expand Up @@ -595,6 +598,7 @@ func createStep(spec *gauge.Specification, stepToken *Token) (*gauge.Step, *Pars
return stepToAdd, parseDetails
}

// CreateStepUsingLookup generates gauge steps from step token and args lookup.
func CreateStepUsingLookup(stepToken *Token, lookup *gauge.ArgLookup, specFileName string) (*gauge.Step, *ParseResult) {
stepValue, argsType := extractStepValueAndParameterTypes(stepToken.Value)
if argsType != nil && len(argsType) != len(stepToken.Args) {
Expand All @@ -620,6 +624,7 @@ func CreateStepUsingLookup(stepToken *Token, lookup *gauge.ArgLookup, specFileNa
return step, &ParseResult{ParseErrors: errors, Warnings: warnings}
}

// ExtractStepArgsFromToken extracts step args(Static and Dynamic) from the given step token.
func ExtractStepArgsFromToken(stepToken *Token) ([]gauge.StepArg, error) {
_, argsType := extractStepValueAndParameterTypes(stepToken.Value)
if argsType != nil && len(argsType) != len(stepToken.Args) {
Expand Down Expand Up @@ -770,6 +775,7 @@ type ParseError struct {
LineText string
}

// Error prints error with filename, line number, error message and step text.
func (se ParseError) Error() string {
if se.LineNo == 0 && se.FileName == "" {
return fmt.Sprintf("%s", se.Message)
Expand All @@ -788,6 +794,7 @@ type ParseResult struct {
FileName string
}

// Errors Prints parse errors and critical errors.
func (result *ParseResult) Errors() (errors []string) {
for _, err := range result.ParseErrors {
errors = append(errors, fmt.Sprintf("[ParseError] %s", err.Error()))
Expand Down
Loading

0 comments on commit c96bdbb

Please sign in to comment.