| package spec |
| |
| import ( |
| "math/rand" |
| "regexp" |
| "sort" |
| ) |
| |
| type Specs struct { |
| specs []*Spec |
| hasProgrammaticFocus bool |
| RegexScansFilePath bool |
| } |
| |
| func NewSpecs(specs []*Spec) *Specs { |
| return &Specs{ |
| specs: specs, |
| } |
| } |
| |
| func (e *Specs) Specs() []*Spec { |
| return e.specs |
| } |
| |
| func (e *Specs) HasProgrammaticFocus() bool { |
| return e.hasProgrammaticFocus |
| } |
| |
| func (e *Specs) Shuffle(r *rand.Rand) { |
| sort.Sort(e) |
| permutation := r.Perm(len(e.specs)) |
| shuffledSpecs := make([]*Spec, len(e.specs)) |
| for i, j := range permutation { |
| shuffledSpecs[i] = e.specs[j] |
| } |
| e.specs = shuffledSpecs |
| } |
| |
| func (e *Specs) ApplyFocus(description string, focusString string, skipString string) { |
| if focusString == "" && skipString == "" { |
| e.applyProgrammaticFocus() |
| } else { |
| e.applyRegExpFocusAndSkip(description, focusString, skipString) |
| } |
| } |
| |
| func (e *Specs) applyProgrammaticFocus() { |
| e.hasProgrammaticFocus = false |
| for _, spec := range e.specs { |
| if spec.Focused() && !spec.Pending() { |
| e.hasProgrammaticFocus = true |
| break |
| } |
| } |
| |
| if e.hasProgrammaticFocus { |
| for _, spec := range e.specs { |
| if !spec.Focused() { |
| spec.Skip() |
| } |
| } |
| } |
| } |
| |
| // toMatch returns a byte[] to be used by regex matchers. When adding new behaviours to the matching function, |
| // this is the place which we append to. |
| func (e *Specs) toMatch(description string, spec *Spec) []byte { |
| if e.RegexScansFilePath { |
| return []byte( |
| description + " " + |
| spec.ConcatenatedString() + " " + |
| spec.subject.CodeLocation().FileName) |
| } else { |
| return []byte( |
| description + " " + |
| spec.ConcatenatedString()) |
| } |
| } |
| |
| func (e *Specs) applyRegExpFocusAndSkip(description string, focusString string, skipString string) { |
| for _, spec := range e.specs { |
| matchesFocus := true |
| matchesSkip := false |
| |
| toMatch := e.toMatch(description, spec) |
| |
| if focusString != "" { |
| focusFilter := regexp.MustCompile(focusString) |
| matchesFocus = focusFilter.Match([]byte(toMatch)) |
| } |
| |
| if skipString != "" { |
| skipFilter := regexp.MustCompile(skipString) |
| matchesSkip = skipFilter.Match([]byte(toMatch)) |
| } |
| |
| if !matchesFocus || matchesSkip { |
| spec.Skip() |
| } |
| } |
| } |
| |
| func (e *Specs) SkipMeasurements() { |
| for _, spec := range e.specs { |
| if spec.IsMeasurement() { |
| spec.Skip() |
| } |
| } |
| } |
| |
| //sort.Interface |
| |
| func (e *Specs) Len() int { |
| return len(e.specs) |
| } |
| |
| func (e *Specs) Less(i, j int) bool { |
| return e.specs[i].ConcatenatedString() < e.specs[j].ConcatenatedString() |
| } |
| |
| func (e *Specs) Swap(i, j int) { |
| e.specs[i], e.specs[j] = e.specs[j], e.specs[i] |
| } |