github.com/getgauge/gauge@v1.6.9/gauge/concept.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package gauge
     8  
     9  type ConceptDictionary struct {
    10  	ConceptsMap     map[string]*Concept
    11  	constructionMap map[string][]*Step
    12  }
    13  
    14  type Concept struct {
    15  	ConceptStep *Step
    16  	FileName    string
    17  }
    18  
    19  func NewConceptDictionary() *ConceptDictionary {
    20  	return &ConceptDictionary{ConceptsMap: make(map[string]*Concept), constructionMap: make(map[string][]*Step)}
    21  }
    22  
    23  func (dict *ConceptDictionary) Search(stepValue string) *Concept {
    24  	if concept, ok := dict.ConceptsMap[stepValue]; ok {
    25  		return concept
    26  	}
    27  	return nil
    28  }
    29  
    30  func (dict *ConceptDictionary) ReplaceNestedConceptSteps(conceptStep *Step) error {
    31  	if err := dict.updateStep(conceptStep); err != nil {
    32  		return err
    33  	}
    34  	for i, stepInsideConcept := range conceptStep.ConceptSteps {
    35  		if nestedConcept := dict.Search(stepInsideConcept.Value); nestedConcept != nil {
    36  			//replace step with actual concept
    37  			conceptStep.ConceptSteps[i].ConceptSteps = nestedConcept.ConceptStep.ConceptSteps
    38  			conceptStep.ConceptSteps[i].IsConcept = nestedConcept.ConceptStep.IsConcept
    39  			lookupCopy, err := nestedConcept.ConceptStep.Lookup.GetCopy()
    40  			if err != nil {
    41  				return err
    42  			}
    43  			conceptStep.ConceptSteps[i].Lookup = *lookupCopy
    44  		} else {
    45  			if err := dict.updateStep(stepInsideConcept); err != nil {
    46  				return err
    47  			}
    48  
    49  		}
    50  	}
    51  	return nil
    52  }
    53  
    54  //mutates the step with concept steps so that anyone who is referencing the step will now refer a concept
    55  func (dict *ConceptDictionary) updateStep(step *Step) error {
    56  	dict.constructionMap[step.Value] = append(dict.constructionMap[step.Value], step)
    57  	if !dict.constructionMap[step.Value][0].IsConcept {
    58  		dict.constructionMap[step.Value] = append(dict.constructionMap[step.Value], step)
    59  		for _, allSteps := range dict.constructionMap[step.Value] {
    60  			allSteps.IsConcept = step.IsConcept
    61  			allSteps.ConceptSteps = step.ConceptSteps
    62  			lookupCopy, err := step.Lookup.GetCopy()
    63  			if err != nil {
    64  				return err
    65  			}
    66  			allSteps.Lookup = *lookupCopy
    67  		}
    68  	}
    69  	return nil
    70  }
    71  
    72  func (dict *ConceptDictionary) UpdateLookupForNestedConcepts() error {
    73  	for _, concept := range dict.ConceptsMap {
    74  		for _, stepInsideConcept := range concept.ConceptStep.ConceptSteps {
    75  			stepInsideConcept.Parent = concept.ConceptStep
    76  			if nestedConcept := dict.Search(stepInsideConcept.Value); nestedConcept != nil {
    77  				for i, arg := range nestedConcept.ConceptStep.Args {
    78  					stepArg := StepArg{ArgType: stepInsideConcept.Args[i].ArgType, Value: stepInsideConcept.Args[i].Value, Table: stepInsideConcept.Args[i].Table}
    79  					if err := stepInsideConcept.Lookup.AddArgValue(arg.Value, &stepArg); err != nil {
    80  						return err
    81  					}
    82  				}
    83  			}
    84  		}
    85  	}
    86  	return nil
    87  }
    88  
    89  func (dict *ConceptDictionary) Remove(stepValue string) {
    90  	delete(dict.ConceptsMap, stepValue)
    91  	delete(dict.constructionMap, stepValue)
    92  }
    93  
    94  type ByLineNo []*Concept
    95  
    96  func (s ByLineNo) Len() int {
    97  	return len(s)
    98  }
    99  
   100  func (s ByLineNo) Swap(i, j int) {
   101  	s[i], s[j] = s[j], s[i]
   102  }
   103  
   104  func (s ByLineNo) Less(i, j int) bool {
   105  	return s[i].ConceptStep.LineNo < s[j].ConceptStep.LineNo
   106  }