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 }