github.com/getgauge/gauge@v1.6.9/filter/specItemFilter_test.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 filter
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/getgauge/gauge/gauge"
    14  	. "gopkg.in/check.v1"
    15  )
    16  
    17  func Test(t *testing.T) { TestingT(t) }
    18  
    19  type MySuite struct{}
    20  
    21  var _ = Suite(&MySuite{})
    22  
    23  func before() {
    24  	os.Setenv("allow_case_sensitive_tags", "false")
    25  }
    26  
    27  func (s *MySuite) TestToEvaluateTagExpressionWithTwoTags(c *C) {
    28  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag1 & tag3"}
    29  	c.Assert(filter.filterTags([]string{"tag1", "tag2"}), Equals, false)
    30  }
    31  
    32  func (s *MySuite) TestToEvaluateTagExpressionWithComplexTagExpression(c *C) {
    33  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag1 & ((tag3 | tag2) & (tag5 | tag4 | tag3) & tag7) | tag6"}
    34  	c.Assert(filter.filterTags([]string{"tag1", "tag2", "tag7", "tag4"}), Equals, true)
    35  }
    36  
    37  func (s *MySuite) TestToEvaluateTagExpressionWithFailingTagExpression(c *C) {
    38  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag1 & ((tag3 | tag2) & (tag5 | tag4 | tag3) & tag7) & tag6"}
    39  	c.Assert(filter.filterTags([]string{"tag1", "tag2", "tag7", "tag4"}), Equals, false)
    40  }
    41  
    42  func (s *MySuite) TestToEvaluateTagExpressionWithWrongTagExpression(c *C) {
    43  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag1 & ((((tag3 | tag2) & (tag5 | tag4 | tag3) & tag7) & tag6"}
    44  	c.Assert(filter.filterTags([]string{"tag1", "tag2", "tag7", "tag4"}), Equals, false)
    45  }
    46  
    47  func (s *MySuite) TestToEvaluateTagExpressionConsistingOfSpaces(c *C) {
    48  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag 1 & tag3"}
    49  	c.Assert(filter.filterTags([]string{"tag 1", "tag3"}), Equals, true)
    50  }
    51  
    52  func (s *MySuite) TestToEvaluateTagExpressionConsistingLogicalNotOperator(c *C) {
    53  	filter := &ScenarioFilterBasedOnTags{tagExpression: "!tag 1 & tag3"}
    54  	c.Assert(filter.filterTags([]string{"tag2", "tag3"}), Equals, true)
    55  }
    56  
    57  func (s *MySuite) TestToEvaluateTagExpressionConsistingManyLogicalNotOperator(c *C) {
    58  	filter := &ScenarioFilterBasedOnTags{tagExpression: "!(!(tag 1 | !(tag6 | !(tag5))) & tag2)"}
    59  	value := filter.filterTags([]string{"tag2", "tag4"})
    60  	c.Assert(value, Equals, true)
    61  }
    62  
    63  func (s *MySuite) TestToEvaluateTagExpressionConsistingParallelLogicalNotOperator(c *C) {
    64  	filter := &ScenarioFilterBasedOnTags{tagExpression: "!(tag1) & ! (tag3 & ! (tag3))"}
    65  	value := filter.filterTags([]string{"tag2", "tag4"})
    66  	c.Assert(value, Equals, true)
    67  }
    68  
    69  func (s *MySuite) TestToEvaluateTagExpressionConsistingComma(c *C) {
    70  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag 1 , tag3"}
    71  	c.Assert(filter.filterTags([]string{"tag2", "tag3"}), Equals, false)
    72  }
    73  
    74  func (s *MySuite) TestToEvaluateTagExpressionConsistingCommaGivesTrue(c *C) {
    75  	filter := &ScenarioFilterBasedOnTags{tagExpression: "tag 1 , tag3"}
    76  	c.Assert(filter.filterTags([]string{"tag1", "tag3"}), Equals, true)
    77  }
    78  
    79  func (s *MySuite) TestToEvaluateTagExpressionConsistingTrueAndFalseAsTagNames(c *C) {
    80  	filter := &ScenarioFilterBasedOnTags{tagExpression: "true , false"}
    81  	c.Assert(filter.filterTags([]string{"true", "false"}), Equals, true)
    82  }
    83  
    84  func (s *MySuite) TestToEvaluateTagExpressionConsistingTrueAndFalseAsTagNamesWithNegation(c *C) {
    85  	filter := &ScenarioFilterBasedOnTags{tagExpression: "!true"}
    86  	c.Assert(filter.filterTags(nil), Equals, true)
    87  }
    88  
    89  func (s *MySuite) TestToEvaluateTagExpressionConsistingSpecialCharacters(c *C) {
    90  	filter := &ScenarioFilterBasedOnTags{tagExpression: "a && b || c | b & b"}
    91  	c.Assert(filter.filterTags([]string{"a", "b"}), Equals, true)
    92  }
    93  
    94  func (s *MySuite) TestToEvaluateTagExpressionWhenTagIsSubsetOfTrueOrFalse(c *C) {
    95  	// https://github.com/getgauge/gauge/issues/667
    96  	filter := &ScenarioFilterBasedOnTags{tagExpression: "b || c | b & b && a"}
    97  	c.Assert(filter.filterTags([]string{"a", "b"}), Equals, true)
    98  }
    99  
   100  func (s *MySuite) TestParseTagExpression(c *C) {
   101  	filter := &ScenarioFilterBasedOnTags{tagExpression: "b || c | b & b && a"}
   102  	txps, tags := filter.parseTagExpression()
   103  
   104  	expectedTxps := []string{"b", "|", "|", "c", "|", "b", "&", "b", "&", "&", "a"}
   105  	expectedTags := []string{"b", "c", "b", "b", "a"}
   106  
   107  	for i, t := range txps {
   108  		c.Assert(expectedTxps[i], Equals, t)
   109  	}
   110  	for i, t := range tags {
   111  		c.Assert(expectedTags[i], Equals, t)
   112  	}
   113  }
   114  
   115  func (s *MySuite) TestScenarioSpanFilter(c *C) {
   116  	scenario1 := &gauge.Scenario{
   117  		Heading: &gauge.Heading{Value: "First Scenario"},
   118  		Span:    &gauge.Span{Start: 1, End: 3},
   119  	}
   120  	scenario2 := &gauge.Scenario{
   121  		Heading: &gauge.Heading{Value: "Second Scenario"},
   122  		Span:    &gauge.Span{Start: 4, End: 6},
   123  	}
   124  	scenario3 := &gauge.Scenario{
   125  		Heading: &gauge.Heading{Value: "Third Scenario"},
   126  		Span:    &gauge.Span{Start: 7, End: 10},
   127  	}
   128  	scenario4 := &gauge.Scenario{
   129  		Heading: &gauge.Heading{Value: "Fourth Scenario"},
   130  		Span:    &gauge.Span{Start: 11, End: 15},
   131  	}
   132  	spec := &gauge.Specification{
   133  		Items:     []gauge.Item{scenario1, scenario2, scenario3, scenario4},
   134  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3, scenario4},
   135  	}
   136  
   137  	specWithFilteredItems, specWithOtherItems := spec.Filter(NewScenarioFilterBasedOnSpan([]int{8}))
   138  
   139  	c.Assert(len(specWithFilteredItems.Scenarios), Equals, 1)
   140  	c.Assert(specWithFilteredItems.Scenarios[0], Equals, scenario3)
   141  
   142  	c.Assert(len(specWithOtherItems.Scenarios), Equals, 3)
   143  	c.Assert(specWithOtherItems.Scenarios[0], Equals, scenario1)
   144  	c.Assert(specWithOtherItems.Scenarios[1], Equals, scenario2)
   145  	c.Assert(specWithOtherItems.Scenarios[2], Equals, scenario4)
   146  }
   147  
   148  func (s *MySuite) TestScenarioSpanFilterLastScenario(c *C) {
   149  	scenario1 := &gauge.Scenario{
   150  		Heading: &gauge.Heading{Value: "First Scenario"},
   151  		Span:    &gauge.Span{Start: 1, End: 3},
   152  	}
   153  	scenario2 := &gauge.Scenario{
   154  		Heading: &gauge.Heading{Value: "Second Scenario"},
   155  		Span:    &gauge.Span{Start: 4, End: 6},
   156  	}
   157  	scenario3 := &gauge.Scenario{
   158  		Heading: &gauge.Heading{Value: "Third Scenario"},
   159  		Span:    &gauge.Span{Start: 7, End: 10},
   160  	}
   161  	scenario4 := &gauge.Scenario{
   162  		Heading: &gauge.Heading{Value: "Fourth Scenario"},
   163  		Span:    &gauge.Span{Start: 11, End: 15},
   164  	}
   165  	spec := &gauge.Specification{
   166  		Items:     []gauge.Item{scenario1, scenario2, scenario3, scenario4},
   167  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3, scenario4},
   168  	}
   169  
   170  	specWithFilteredItems, specWithOtherItems := spec.Filter(NewScenarioFilterBasedOnSpan([]int{13}))
   171  	c.Assert(len(specWithFilteredItems.Scenarios), Equals, 1)
   172  	c.Assert(specWithFilteredItems.Scenarios[0], Equals, scenario4)
   173  
   174  	c.Assert(len(specWithOtherItems.Scenarios), Equals, 3)
   175  	c.Assert(specWithOtherItems.Scenarios[0], Equals, scenario1)
   176  	c.Assert(specWithOtherItems.Scenarios[1], Equals, scenario2)
   177  	c.Assert(specWithOtherItems.Scenarios[2], Equals, scenario3)
   178  
   179  }
   180  
   181  func (s *MySuite) TestScenarioSpanFilterFirstScenario(c *C) {
   182  	scenario1 := &gauge.Scenario{
   183  		Heading: &gauge.Heading{Value: "First Scenario"},
   184  		Span:    &gauge.Span{Start: 1, End: 3},
   185  	}
   186  	scenario2 := &gauge.Scenario{
   187  		Heading: &gauge.Heading{Value: "Second Scenario"},
   188  		Span:    &gauge.Span{Start: 4, End: 6},
   189  	}
   190  	scenario3 := &gauge.Scenario{
   191  		Heading: &gauge.Heading{Value: "Third Scenario"},
   192  		Span:    &gauge.Span{Start: 7, End: 10},
   193  	}
   194  	scenario4 := &gauge.Scenario{
   195  		Heading: &gauge.Heading{Value: "Fourth Scenario"},
   196  		Span:    &gauge.Span{Start: 11, End: 15},
   197  	}
   198  	spec := &gauge.Specification{
   199  		Items:     []gauge.Item{scenario1, scenario2, scenario3, scenario4},
   200  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3, scenario4},
   201  	}
   202  
   203  	specWithFilteredItems, specWithOtherItems := spec.Filter(NewScenarioFilterBasedOnSpan([]int{2}))
   204  
   205  	c.Assert(len(specWithFilteredItems.Scenarios), Equals, 1)
   206  	c.Assert(specWithFilteredItems.Scenarios[0], Equals, scenario1)
   207  
   208  	c.Assert(len(specWithOtherItems.Scenarios), Equals, 3)
   209  	c.Assert(specWithOtherItems.Scenarios[0], Equals, scenario2)
   210  	c.Assert(specWithOtherItems.Scenarios[1], Equals, scenario3)
   211  	c.Assert(specWithOtherItems.Scenarios[2], Equals, scenario4)
   212  
   213  }
   214  
   215  func (s *MySuite) TestScenarioSpanFilterForSingleScenarioSpec(c *C) {
   216  	scenario1 := &gauge.Scenario{
   217  		Heading: &gauge.Heading{Value: "First Scenario"},
   218  		Span:    &gauge.Span{Start: 1, End: 3},
   219  	}
   220  	spec := &gauge.Specification{
   221  		Items:     []gauge.Item{scenario1},
   222  		Scenarios: []*gauge.Scenario{scenario1},
   223  	}
   224  
   225  	specWithFilteredItems, specWithOtherItems := spec.Filter(NewScenarioFilterBasedOnSpan([]int{3}))
   226  	c.Assert(len(specWithFilteredItems.Scenarios), Equals, 1)
   227  	c.Assert(specWithFilteredItems.Scenarios[0], Equals, scenario1)
   228  
   229  	c.Assert(len(specWithOtherItems.Scenarios), Equals, 0)
   230  }
   231  
   232  func (s *MySuite) TestScenarioSpanFilterWithWrongScenarioIndex(c *C) {
   233  	scenario1 := &gauge.Scenario{
   234  		Heading: &gauge.Heading{Value: "First Scenario"},
   235  		Span:    &gauge.Span{Start: 1, End: 3},
   236  	}
   237  	spec := &gauge.Specification{
   238  		Items:     []gauge.Item{scenario1},
   239  		Scenarios: []*gauge.Scenario{scenario1},
   240  	}
   241  
   242  	specWithFilteredItems, specWithOtherItems := spec.Filter(NewScenarioFilterBasedOnSpan([]int{5}))
   243  	c.Assert(len(specWithFilteredItems.Scenarios), Equals, 0)
   244  
   245  	c.Assert(len(specWithOtherItems.Scenarios), Equals, 1)
   246  	c.Assert(specWithOtherItems.Scenarios[0], Equals, scenario1)
   247  }
   248  
   249  func (s *MySuite) TestScenarioSpanFilterWithMultipleLineNumbers(c *C) {
   250  	scenario1 := &gauge.Scenario{
   251  		Heading: &gauge.Heading{Value: "First Scenario"},
   252  		Span:    &gauge.Span{Start: 1, End: 3},
   253  	}
   254  	scenario2 := &gauge.Scenario{
   255  		Heading: &gauge.Heading{Value: "Second Scenario"},
   256  		Span:    &gauge.Span{Start: 4, End: 6},
   257  	}
   258  	scenario3 := &gauge.Scenario{
   259  		Heading: &gauge.Heading{Value: "Third Scenario"},
   260  		Span:    &gauge.Span{Start: 7, End: 10},
   261  	}
   262  	scenario4 := &gauge.Scenario{
   263  		Heading: &gauge.Heading{Value: "Fourth Scenario"},
   264  		Span:    &gauge.Span{Start: 11, End: 15},
   265  	}
   266  	spec := &gauge.Specification{
   267  		Items:     []gauge.Item{scenario1, scenario2, scenario3, scenario4},
   268  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3, scenario4},
   269  	}
   270  
   271  	specWithFilteredItems, specWithOtherItems := spec.Filter(NewScenarioFilterBasedOnSpan([]int{3, 13}))
   272  
   273  	c.Assert(len(specWithFilteredItems.Scenarios), Equals, 2)
   274  	c.Assert(specWithFilteredItems.Scenarios[0], Equals, scenario1)
   275  	c.Assert(specWithFilteredItems.Scenarios[1], Equals, scenario4)
   276  
   277  	c.Assert(len(specWithOtherItems.Scenarios), Equals, 2)
   278  	c.Assert(specWithOtherItems.Scenarios[0], Equals, scenario2)
   279  	c.Assert(specWithOtherItems.Scenarios[1], Equals, scenario3)
   280  
   281  }
   282  
   283  func (s *MySuite) TestToFilterSpecsByTagExpOfTwoTags(c *C) {
   284  	myTags := []string{"tag1", "tag2"}
   285  	scenario1 := &gauge.Scenario{
   286  		Heading: &gauge.Heading{Value: "First Scenario"},
   287  		Span:    &gauge.Span{Start: 1, End: 3},
   288  	}
   289  	scenario2 := &gauge.Scenario{
   290  		Heading: &gauge.Heading{Value: "Second Scenario"},
   291  		Span:    &gauge.Span{Start: 4, End: 6},
   292  	}
   293  	spec1 := &gauge.Specification{
   294  		Items:     []gauge.Item{scenario1, scenario2},
   295  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   296  		Tags:      &gauge.Tags{RawValues: [][]string{myTags}},
   297  	}
   298  
   299  	spec2 := &gauge.Specification{
   300  		Items:     []gauge.Item{scenario1, scenario2},
   301  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   302  	}
   303  
   304  	var specs []*gauge.Specification
   305  	specs = append(specs, spec1, spec2)
   306  
   307  	c.Assert(specs[0].Tags.Values()[0], Equals, myTags[0])
   308  	c.Assert(specs[0].Tags.Values()[1], Equals, myTags[1])
   309  
   310  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag2")
   311  	c.Assert(len(filteredSpecs), Equals, 1)
   312  
   313  	c.Assert(len(otherSpecs), Equals, 1)
   314  }
   315  
   316  func (s *MySuite) TestToEvaluateTagExpression(c *C) {
   317  	myTags := []string{"tag1", "tag2"}
   318  
   319  	scenario1 := &gauge.Scenario{
   320  		Heading: &gauge.Heading{Value: "First Scenario"},
   321  		Span:    &gauge.Span{Start: 1, End: 3},
   322  		Tags:    &gauge.Tags{RawValues: [][]string{{myTags[0]}}},
   323  	}
   324  	scenario2 := &gauge.Scenario{
   325  		Heading: &gauge.Heading{Value: "Second Scenario"},
   326  		Span:    &gauge.Span{Start: 4, End: 6},
   327  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag3"}}},
   328  	}
   329  
   330  	scenario3 := &gauge.Scenario{
   331  		Heading: &gauge.Heading{Value: "Third Scenario"},
   332  		Span:    &gauge.Span{Start: 1, End: 3},
   333  	}
   334  	scenario4 := &gauge.Scenario{
   335  		Heading: &gauge.Heading{Value: "Fourth Scenario"},
   336  		Span:    &gauge.Span{Start: 4, End: 6},
   337  	}
   338  
   339  	spec1 := &gauge.Specification{
   340  		Items:     []gauge.Item{scenario1, scenario2},
   341  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   342  	}
   343  
   344  	spec2 := &gauge.Specification{
   345  		Items:     []gauge.Item{scenario3, scenario4},
   346  		Scenarios: []*gauge.Scenario{scenario3, scenario4},
   347  		Tags:      &gauge.Tags{RawValues: [][]string{myTags}},
   348  	}
   349  
   350  	var specs []*gauge.Specification
   351  	specs = append(specs, spec1, spec2)
   352  
   353  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & !(tag1 & tag4) & (tag2 | tag3)")
   354  	c.Assert(len(filteredSpecs), Equals, 1)
   355  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 2)
   356  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario3)
   357  	c.Assert(filteredSpecs[0].Scenarios[1], Equals, scenario4)
   358  
   359  	c.Assert(len(otherSpecs), Equals, 1)
   360  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 2)
   361  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario1)
   362  	c.Assert(otherSpecs[0].Scenarios[1], Equals, scenario2)
   363  }
   364  
   365  func (s *MySuite) TestToFilterSpecsByWrongTagExpression(c *C) {
   366  	myTags := []string{"tag1", "tag2"}
   367  	scenario1 := &gauge.Scenario{
   368  		Heading: &gauge.Heading{Value: "First Scenario"},
   369  		Span:    &gauge.Span{Start: 1, End: 3},
   370  	}
   371  	scenario2 := &gauge.Scenario{
   372  		Heading: &gauge.Heading{Value: "Second Scenario"},
   373  		Span:    &gauge.Span{Start: 4, End: 6},
   374  	}
   375  	spec1 := &gauge.Specification{
   376  		Items:     []gauge.Item{scenario1, scenario2},
   377  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   378  		Tags:      &gauge.Tags{RawValues: [][]string{myTags}},
   379  	}
   380  
   381  	spec2 := &gauge.Specification{
   382  		Items:     []gauge.Item{scenario1, scenario2},
   383  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   384  	}
   385  
   386  	var specs []*gauge.Specification
   387  	specs = append(specs, spec1, spec2)
   388  
   389  	c.Assert(specs[0].Tags.Values()[0], Equals, myTags[0])
   390  	c.Assert(specs[0].Tags.Values()[1], Equals, myTags[1])
   391  
   392  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "(tag1 & tag2")
   393  	c.Assert(len(filteredSpecs), Equals, 0)
   394  
   395  	c.Assert(len(otherSpecs), Equals, 2)
   396  
   397  }
   398  
   399  func (s *MySuite) TestToFilterMultipleScenariosByMultipleTags(c *C) {
   400  	myTags := []string{"tag1", "tag2"}
   401  	scenario1 := &gauge.Scenario{
   402  		Heading: &gauge.Heading{Value: "First Scenario"},
   403  		Span:    &gauge.Span{Start: 1, End: 3},
   404  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag1"}}},
   405  	}
   406  	scenario2 := &gauge.Scenario{
   407  		Heading: &gauge.Heading{Value: "Second Scenario"},
   408  		Span:    &gauge.Span{Start: 4, End: 6},
   409  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   410  	}
   411  
   412  	scenario3 := &gauge.Scenario{
   413  		Heading: &gauge.Heading{Value: "Third Scenario"},
   414  		Span:    &gauge.Span{Start: 1, End: 3},
   415  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   416  	}
   417  	scenario4 := &gauge.Scenario{
   418  		Heading: &gauge.Heading{Value: "Fourth Scenario"},
   419  		Span:    &gauge.Span{Start: 4, End: 6},
   420  		Tags:    &gauge.Tags{RawValues: [][]string{{"prod", "tag7", "tag1", "tag2"}}},
   421  	}
   422  	spec1 := &gauge.Specification{
   423  		Items:     []gauge.Item{scenario1, scenario2, scenario3, scenario4},
   424  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3, scenario4},
   425  	}
   426  
   427  	var specs []*gauge.Specification
   428  	specs = append(specs, spec1)
   429  
   430  	c.Assert(len(specs[0].Scenarios), Equals, 4)
   431  	c.Assert(len(specs[0].Scenarios[0].Tags.Values()), Equals, 1)
   432  	c.Assert(len(specs[0].Scenarios[1].Tags.Values()), Equals, 2)
   433  	c.Assert(len(specs[0].Scenarios[2].Tags.Values()), Equals, 2)
   434  	c.Assert(len(specs[0].Scenarios[3].Tags.Values()), Equals, 4)
   435  
   436  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag2")
   437  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 3)
   438  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario2)
   439  	c.Assert(filteredSpecs[0].Scenarios[1], Equals, scenario3)
   440  	c.Assert(filteredSpecs[0].Scenarios[2], Equals, scenario4)
   441  
   442  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 1)
   443  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario1)
   444  
   445  }
   446  
   447  func (s *MySuite) TestToFilterScenariosByTagsAtSpecLevel(c *C) {
   448  	myTags := []string{"tag1", "tag2"}
   449  
   450  	scenario1 := &gauge.Scenario{
   451  		Heading: &gauge.Heading{Value: "First Scenario"},
   452  		Span:    &gauge.Span{Start: 1, End: 3},
   453  	}
   454  	scenario2 := &gauge.Scenario{
   455  		Heading: &gauge.Heading{Value: "Second Scenario"},
   456  		Span:    &gauge.Span{Start: 4, End: 6},
   457  	}
   458  
   459  	scenario3 := &gauge.Scenario{
   460  		Heading: &gauge.Heading{Value: "Third Scenario"},
   461  		Span:    &gauge.Span{Start: 4, End: 6},
   462  	}
   463  
   464  	spec1 := &gauge.Specification{
   465  		Items:     []gauge.Item{scenario1, scenario2, scenario3},
   466  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   467  		Tags:      &gauge.Tags{RawValues: [][]string{myTags}},
   468  	}
   469  
   470  	var specs []*gauge.Specification
   471  	specs = append(specs, spec1)
   472  
   473  	c.Assert(len(specs[0].Scenarios), Equals, 3)
   474  	c.Assert(len(specs[0].Tags.Values()), Equals, 2)
   475  
   476  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag2")
   477  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 3)
   478  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario1)
   479  	c.Assert(filteredSpecs[0].Scenarios[1], Equals, scenario2)
   480  	c.Assert(filteredSpecs[0].Scenarios[2], Equals, scenario3)
   481  
   482  	c.Assert(len(otherSpecs), Equals, 0)
   483  
   484  }
   485  
   486  func (s *MySuite) TestToFilterScenariosByTagExpWithDuplicateTagNames(c *C) {
   487  	myTags := []string{"tag1", "tag12"}
   488  	scenario1 := &gauge.Scenario{
   489  		Heading: &gauge.Heading{Value: "First Scenario"},
   490  		Span:    &gauge.Span{Start: 1, End: 3},
   491  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   492  	}
   493  	scenario2 := &gauge.Scenario{
   494  		Heading: &gauge.Heading{Value: "Second Scenario"},
   495  		Span:    &gauge.Span{Start: 4, End: 6},
   496  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag1"}}},
   497  	}
   498  
   499  	scenario3 := &gauge.Scenario{
   500  		Heading: &gauge.Heading{Value: "Third Scenario"},
   501  		Span:    &gauge.Span{Start: 4, End: 6},
   502  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag12"}}},
   503  	}
   504  
   505  	spec1 := &gauge.Specification{
   506  		Items:     []gauge.Item{scenario1, scenario2, scenario3},
   507  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   508  	}
   509  
   510  	var specs []*gauge.Specification
   511  	specs = append(specs, spec1)
   512  	c.Assert(len(specs), Equals, 1)
   513  
   514  	c.Assert(len(specs[0].Scenarios), Equals, 3)
   515  
   516  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag12")
   517  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 1)
   518  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario1)
   519  
   520  	c.Assert(len(otherSpecs), Equals, 1)
   521  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario2)
   522  	c.Assert(otherSpecs[0].Scenarios[1], Equals, scenario3)
   523  }
   524  
   525  func (s *MySuite) TestFilterTags(c *C) {
   526  	specTags := []string{"abcd", "foo", "bar", "foo bar"}
   527  	tagFilter := NewScenarioFilterBasedOnTags(specTags, "abcd & foo bar")
   528  	evaluateTrue := tagFilter.filterTags(specTags)
   529  	c.Assert(evaluateTrue, Equals, true)
   530  }
   531  
   532  func (s *MySuite) TestFilterMixedCaseTags(c *C) {
   533  	before()
   534  	specTags := []string{"abcd", "foo", "BAR", "foo bar"}
   535  	tagFilter := NewScenarioFilterBasedOnTags(specTags, "abcd & FOO bar")
   536  	evaluateTrue := tagFilter.filterTags(specTags)
   537  	c.Assert(evaluateTrue, Equals, true)
   538  }
   539  
   540  func (s *MySuite) TestSanitizeTags(c *C) {
   541  	specTags := []string{"abcd", "foo", "bar", "foo bar"}
   542  	tagFilter := NewScenarioFilterBasedOnTags(specTags, "abcd & foo bar | true")
   543  	evaluateTrue := tagFilter.filterTags(specTags)
   544  	c.Assert(evaluateTrue, Equals, true)
   545  }
   546  
   547  func (s *MySuite) TestSanitizeMixedCaseTags(c *C) {
   548  	before()
   549  	specTags := []string{"abcd", "foo", "bar", "foo bar"}
   550  	tagFilter := NewScenarioFilterBasedOnTags(specTags, "abcd & foo Bar | true")
   551  	evaluateTrue := tagFilter.filterTags(specTags)
   552  	c.Assert(evaluateTrue, Equals, true)
   553  }
   554  
   555  func (s *MySuite) TestToFilterSpecsByTags(c *C) {
   556  	myTags := []string{"tag1", "tag2"}
   557  	scenario1 := &gauge.Scenario{
   558  		Heading: &gauge.Heading{Value: "First Scenario"},
   559  		Span:    &gauge.Span{Start: 1, End: 3},
   560  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   561  	}
   562  	scenario2 := &gauge.Scenario{
   563  		Heading: &gauge.Heading{Value: "Second Scenario"},
   564  		Span:    &gauge.Span{Start: 4, End: 6},
   565  	}
   566  	scenario3 := &gauge.Scenario{
   567  		Heading: &gauge.Heading{Value: "Third Scenario"},
   568  		Span:    &gauge.Span{Start: 1, End: 3},
   569  	}
   570  
   571  	spec1 := &gauge.Specification{
   572  		Items:     []gauge.Item{scenario1, scenario2},
   573  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   574  	}
   575  	spec2 := &gauge.Specification{
   576  		Items:     []gauge.Item{scenario2, scenario3},
   577  		Scenarios: []*gauge.Scenario{scenario2, scenario3},
   578  	}
   579  
   580  	spec3 := &gauge.Specification{
   581  		Items:     []gauge.Item{scenario1, scenario3},
   582  		Scenarios: []*gauge.Scenario{scenario1, scenario3},
   583  	}
   584  
   585  	var specs []*gauge.Specification
   586  	specs = append(specs, spec1, spec2, spec3)
   587  
   588  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag2")
   589  	c.Assert(len(filteredSpecs), Equals, 2)
   590  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 1)
   591  	c.Assert(len(filteredSpecs[1].Scenarios), Equals, 1)
   592  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario1)
   593  	c.Assert(filteredSpecs[1].Scenarios[0], Equals, scenario1)
   594  
   595  	c.Assert(len(otherSpecs), Equals, 3)
   596  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 1)
   597  	c.Assert(len(otherSpecs[1].Scenarios), Equals, 2)
   598  	c.Assert(len(otherSpecs[2].Scenarios), Equals, 1)
   599  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario2)
   600  	c.Assert(otherSpecs[1].Scenarios[0], Equals, scenario2)
   601  	c.Assert(otherSpecs[1].Scenarios[1], Equals, scenario3)
   602  	c.Assert(otherSpecs[2].Scenarios[0], Equals, scenario3)
   603  
   604  }
   605  
   606  func (s *MySuite) TestToFilterSpecsByMixedCaseTags(c *C) {
   607  	before()
   608  	myTags := []string{"tag1", "TAG2"}
   609  	scenario1 := &gauge.Scenario{
   610  		Heading: &gauge.Heading{Value: "First Scenario"},
   611  		Span:    &gauge.Span{Start: 1, End: 3},
   612  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   613  	}
   614  	scenario2 := &gauge.Scenario{
   615  		Heading: &gauge.Heading{Value: "Second Scenario"},
   616  		Span:    &gauge.Span{Start: 4, End: 6},
   617  	}
   618  	scenario3 := &gauge.Scenario{
   619  		Heading: &gauge.Heading{Value: "Third Scenario"},
   620  		Span:    &gauge.Span{Start: 1, End: 3},
   621  	}
   622  
   623  	spec1 := &gauge.Specification{
   624  		Items:     []gauge.Item{scenario1, scenario2},
   625  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   626  	}
   627  	spec2 := &gauge.Specification{
   628  		Items:     []gauge.Item{scenario2, scenario3},
   629  		Scenarios: []*gauge.Scenario{scenario2, scenario3},
   630  	}
   631  
   632  	spec3 := &gauge.Specification{
   633  		Items:     []gauge.Item{scenario1, scenario3},
   634  		Scenarios: []*gauge.Scenario{scenario1, scenario3},
   635  	}
   636  
   637  	var specs []*gauge.Specification
   638  	specs = append(specs, spec1, spec2, spec3)
   639  
   640  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & Tag2")
   641  	c.Assert(len(filteredSpecs), Equals, 2)
   642  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 1)
   643  	c.Assert(len(filteredSpecs[1].Scenarios), Equals, 1)
   644  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario1)
   645  	c.Assert(filteredSpecs[1].Scenarios[0], Equals, scenario1)
   646  
   647  	c.Assert(len(otherSpecs), Equals, 3)
   648  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 1)
   649  	c.Assert(len(otherSpecs[1].Scenarios), Equals, 2)
   650  	c.Assert(len(otherSpecs[2].Scenarios), Equals, 1)
   651  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario2)
   652  	c.Assert(otherSpecs[1].Scenarios[0], Equals, scenario2)
   653  	c.Assert(otherSpecs[1].Scenarios[1], Equals, scenario3)
   654  	c.Assert(otherSpecs[2].Scenarios[0], Equals, scenario3)
   655  
   656  }
   657  
   658  func (s *MySuite) TestToFilterScenariosByTag(c *C) {
   659  	myTags := []string{"tag1", "tag2"}
   660  
   661  	scenario1 := &gauge.Scenario{
   662  		Heading: &gauge.Heading{Value: "First Scenario"},
   663  		Span:    &gauge.Span{Start: 1, End: 3},
   664  	}
   665  	scenario2 := &gauge.Scenario{
   666  		Heading: &gauge.Heading{Value: "Second Scenario"},
   667  		Span:    &gauge.Span{Start: 4, End: 6},
   668  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   669  	}
   670  
   671  	scenario3 := &gauge.Scenario{
   672  		Heading: &gauge.Heading{Value: "Third Scenario"},
   673  		Span:    &gauge.Span{Start: 4, End: 6},
   674  	}
   675  
   676  	spec1 := &gauge.Specification{
   677  		Items:     []gauge.Item{scenario1, scenario2, scenario3},
   678  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   679  	}
   680  
   681  	var specs []*gauge.Specification
   682  	specs = append(specs, spec1)
   683  
   684  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag2")
   685  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 1)
   686  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario2)
   687  
   688  	c.Assert(len(otherSpecs), Equals, 1)
   689  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 2)
   690  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario1)
   691  	c.Assert(otherSpecs[0].Scenarios[1], Equals, scenario3)
   692  }
   693  
   694  func (s *MySuite) TestToFilterScenariosByMixedCaseTag(c *C) {
   695  	before()
   696  	myTags := []string{"Tag-1", "tag2"}
   697  
   698  	scenario1 := &gauge.Scenario{
   699  		Heading: &gauge.Heading{Value: "First Scenario"},
   700  		Span:    &gauge.Span{Start: 1, End: 3},
   701  	}
   702  	scenario2 := &gauge.Scenario{
   703  		Heading: &gauge.Heading{Value: "Second Scenario"},
   704  		Span:    &gauge.Span{Start: 4, End: 6},
   705  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   706  	}
   707  
   708  	scenario3 := &gauge.Scenario{
   709  		Heading: &gauge.Heading{Value: "Third Scenario"},
   710  		Span:    &gauge.Span{Start: 4, End: 6},
   711  	}
   712  
   713  	spec1 := &gauge.Specification{
   714  		Items:     []gauge.Item{scenario1, scenario2, scenario3},
   715  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   716  	}
   717  
   718  	var specs []*gauge.Specification
   719  	specs = append(specs, spec1)
   720  
   721  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag-1 & tag2")
   722  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 1)
   723  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario2)
   724  
   725  	c.Assert(len(otherSpecs), Equals, 1)
   726  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 2)
   727  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario1)
   728  	c.Assert(otherSpecs[0].Scenarios[1], Equals, scenario3)
   729  }
   730  
   731  func (s *MySuite) TestToFilterMultipleScenariosByTags(c *C) {
   732  	myTags := []string{"tag1", "tag2"}
   733  
   734  	scenario1 := &gauge.Scenario{
   735  		Heading: &gauge.Heading{Value: "First Scenario"},
   736  		Span:    &gauge.Span{Start: 1, End: 3},
   737  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag1"}}},
   738  	}
   739  	scenario2 := &gauge.Scenario{
   740  		Heading: &gauge.Heading{Value: "Second Scenario"},
   741  		Span:    &gauge.Span{Start: 4, End: 6},
   742  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   743  	}
   744  
   745  	scenario3 := &gauge.Scenario{
   746  		Heading: &gauge.Heading{Value: "Third Scenario"},
   747  		Span:    &gauge.Span{Start: 4, End: 6},
   748  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   749  	}
   750  
   751  	spec1 := &gauge.Specification{
   752  		Items:     []gauge.Item{scenario1, scenario2, scenario3},
   753  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   754  	}
   755  
   756  	var specs []*gauge.Specification
   757  	specs = append(specs, spec1)
   758  
   759  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag1 & tag2")
   760  
   761  	c.Assert(len(filteredSpecs[0].Scenarios), Equals, 2)
   762  	c.Assert(filteredSpecs[0].Scenarios[0], Equals, scenario2)
   763  	c.Assert(filteredSpecs[0].Scenarios[1], Equals, scenario3)
   764  
   765  	c.Assert(len(otherSpecs), Equals, 1)
   766  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 1)
   767  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario1)
   768  }
   769  
   770  func (s *MySuite) TestToFilterScenariosByUnavailableTags(c *C) {
   771  	myTags := []string{"tag1", "tag2"}
   772  	scenario1 := &gauge.Scenario{
   773  		Heading: &gauge.Heading{Value: "First Scenario"},
   774  		Span:    &gauge.Span{Start: 1, End: 3},
   775  	}
   776  	scenario2 := &gauge.Scenario{
   777  		Heading: &gauge.Heading{Value: "Second Scenario"},
   778  		Span:    &gauge.Span{Start: 4, End: 6},
   779  		Tags:    &gauge.Tags{RawValues: [][]string{myTags}},
   780  	}
   781  
   782  	scenario3 := &gauge.Scenario{
   783  		Heading: &gauge.Heading{Value: "Third Scenario"},
   784  		Span:    &gauge.Span{Start: 4, End: 6},
   785  	}
   786  
   787  	spec1 := &gauge.Specification{
   788  		Items:     []gauge.Item{scenario1, scenario2, scenario3},
   789  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   790  	}
   791  
   792  	var specs []*gauge.Specification
   793  	specs = append(specs, spec1)
   794  
   795  	filteredSpecs, otherSpecs := filterSpecsByTags(specs, "tag3")
   796  
   797  	c.Assert(len(filteredSpecs), Equals, 0)
   798  
   799  	c.Assert(len(otherSpecs), Equals, 1)
   800  	c.Assert(len(otherSpecs[0].Scenarios), Equals, 3)
   801  	c.Assert(otherSpecs[0].Scenarios[0], Equals, scenario1)
   802  	c.Assert(otherSpecs[0].Scenarios[1], Equals, scenario2)
   803  	c.Assert(otherSpecs[0].Scenarios[2], Equals, scenario3)
   804  }
   805  
   806  func (s *MySuite) TestFilterScenariosByName(c *C) {
   807  	scenario1 := &gauge.Scenario{
   808  		Heading: &gauge.Heading{Value: "First Scenario"},
   809  	}
   810  	scenario2 := &gauge.Scenario{
   811  		Heading: &gauge.Heading{Value: "Second Scenario"},
   812  	}
   813  	spec1 := &gauge.Specification{
   814  		Items:     []gauge.Item{scenario1, scenario2},
   815  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   816  	}
   817  	var scenarios = []string{"First Scenario"}
   818  
   819  	var specs []*gauge.Specification
   820  	specs = append(specs, spec1)
   821  
   822  	c.Assert(len(specs[0].Scenarios), Equals, 2)
   823  	specs = filterSpecsByScenarioName(specs, scenarios)
   824  	c.Assert(len(specs[0].Scenarios), Equals, 1)
   825  }
   826  
   827  func (s *MySuite) TestFilterScenarioWhichDoesNotExists(c *C) {
   828  	scenario1 := &gauge.Scenario{
   829  		Heading: &gauge.Heading{Value: "First Scenario"},
   830  	}
   831  	scenario2 := &gauge.Scenario{
   832  		Heading: &gauge.Heading{Value: "Second Scenario"},
   833  	}
   834  	spec1 := &gauge.Specification{
   835  		Items:     []gauge.Item{scenario1, scenario2},
   836  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   837  	}
   838  	var scenarios = []string{"Third Scenario"}
   839  
   840  	var specs []*gauge.Specification
   841  	specs = append(specs, spec1)
   842  
   843  	c.Assert(len(specs[0].Scenarios), Equals, 2)
   844  	specs = filterSpecsByScenarioName(specs, scenarios)
   845  	c.Assert(len(specs), Equals, 0)
   846  }
   847  
   848  func (s *MySuite) TestFilterMultipleScenariosByName(c *C) {
   849  	scenario1 := &gauge.Scenario{
   850  		Heading: &gauge.Heading{Value: "First Scenario"},
   851  	}
   852  	scenario2 := &gauge.Scenario{
   853  		Heading: &gauge.Heading{Value: "Second Scenario"},
   854  	}
   855  	spec1 := &gauge.Specification{
   856  		Items:     []gauge.Item{scenario1, scenario2},
   857  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   858  	}
   859  	var scenarios = []string{"First Scenario", "Second Scenario"}
   860  
   861  	var specs []*gauge.Specification
   862  	specs = append(specs, spec1)
   863  
   864  	c.Assert(len(specs[0].Scenarios), Equals, 2)
   865  	specs = filterSpecsByScenarioName(specs, scenarios)
   866  	c.Assert(len(specs[0].Scenarios), Equals, 2)
   867  }
   868  
   869  func (s *MySuite) TestFilterInvalidScenarios(c *C) {
   870  	scenario1 := &gauge.Scenario{
   871  		Heading: &gauge.Heading{Value: "First Scenario"},
   872  	}
   873  	scenario2 := &gauge.Scenario{
   874  		Heading: &gauge.Heading{Value: "Second Scenario"},
   875  	}
   876  	spec1 := &gauge.Specification{
   877  		Items:     []gauge.Item{scenario1, scenario2},
   878  		Scenarios: []*gauge.Scenario{scenario1, scenario2},
   879  	}
   880  	var scenarios = []string{"First Scenario", "Third Scenario"}
   881  
   882  	var specs []*gauge.Specification
   883  	specs = append(specs, spec1)
   884  
   885  	c.Assert(len(specs[0].Scenarios), Equals, 2)
   886  	filteredScenarios := filterValidScenarios(specs, scenarios)
   887  	c.Assert(len(filteredScenarios), Equals, 1)
   888  	c.Assert(filteredScenarios[0], Equals, "First Scenario")
   889  }
   890  func (s *MySuite) TestScenarioTagFilterShouldNotRemoveNonScenarioKindItems(c *C) {
   891  	scenario1 := &gauge.Scenario{
   892  		Heading: &gauge.Heading{Value: "First Scenario"},
   893  		Span:    &gauge.Span{Start: 1, End: 3},
   894  	}
   895  	scenario2 := &gauge.Scenario{
   896  		Heading: &gauge.Heading{Value: "Second Scenario"},
   897  		Span:    &gauge.Span{Start: 4, End: 6},
   898  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag2"}}},
   899  	}
   900  	scenario3 := &gauge.Scenario{
   901  		Heading: &gauge.Heading{Value: "Third Scenario"},
   902  		Span:    &gauge.Span{Start: 7, End: 10},
   903  		Tags:    &gauge.Tags{RawValues: [][]string{{"tag1"}}},
   904  	}
   905  	spec := &gauge.Specification{
   906  		Items:     []gauge.Item{scenario1, scenario2, scenario3, &gauge.Table{}, &gauge.Comment{Value: "Comment", LineNo: 1}, &gauge.Step{}},
   907  		Scenarios: []*gauge.Scenario{scenario1, scenario2, scenario3},
   908  	}
   909  
   910  	specWithFilteredItems, specWithOtherItems := filterSpecsByTags([]*gauge.Specification{spec}, "tag1 | tag2")
   911  
   912  	c.Assert(len(specWithFilteredItems), Equals, 1)
   913  	c.Assert(len(specWithFilteredItems[0].Items), Equals, 5)
   914  
   915  	c.Assert(len(specWithOtherItems), Equals, 1)
   916  	c.Assert(len(specWithOtherItems[0].Items), Equals, 4)
   917  }