Merge pull request #306 from cucumber/store-gherkin-ast-in-storage
Added features to the in-mem storage
Этот коммит содержится в:
коммит
a57f082852
13 изменённых файлов: 220 добавлений и 237 удалений
65
fmt.go
65
fmt.go
|
@ -174,7 +174,6 @@ type basefmt struct {
|
||||||
storage *storage
|
storage *storage
|
||||||
|
|
||||||
startedAt time.Time
|
startedAt time.Time
|
||||||
features []*feature
|
|
||||||
|
|
||||||
firstFeature *bool
|
firstFeature *bool
|
||||||
lock *sync.Mutex
|
lock *sync.Mutex
|
||||||
|
@ -184,60 +183,6 @@ func (f *basefmt) setStorage(st *storage) {
|
||||||
f.storage = st
|
f.storage = st
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *basefmt) lastFeature() *feature {
|
|
||||||
return f.features[len(f.features)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) findFeature(scenarioAstID string) *feature {
|
|
||||||
for _, ft := range f.features {
|
|
||||||
if sc := ft.findScenario(scenarioAstID); sc != nil {
|
|
||||||
return ft
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("Couldn't find scenario for AST ID: " + scenarioAstID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) findScenario(scenarioAstID string) *messages.GherkinDocument_Feature_Scenario {
|
|
||||||
for _, ft := range f.features {
|
|
||||||
if sc := ft.findScenario(scenarioAstID); sc != nil {
|
|
||||||
return sc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("Couldn't find scenario for AST ID: " + scenarioAstID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) findBackground(scenarioAstID string) *messages.GherkinDocument_Feature_Background {
|
|
||||||
for _, ft := range f.features {
|
|
||||||
if bg := ft.findBackground(scenarioAstID); bg != nil {
|
|
||||||
return bg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) findExample(exampleAstID string) (*messages.GherkinDocument_Feature_Scenario_Examples, *messages.GherkinDocument_Feature_TableRow) {
|
|
||||||
for _, ft := range f.features {
|
|
||||||
if es, rs := ft.findExample(exampleAstID); es != nil && rs != nil {
|
|
||||||
return es, rs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) findStep(stepAstID string) *messages.GherkinDocument_Feature_Step {
|
|
||||||
for _, ft := range f.features {
|
|
||||||
if st := ft.findStep(stepAstID); st != nil {
|
|
||||||
return st
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("Couldn't find step for AST ID: " + stepAstID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) TestRunStarted() {
|
func (f *basefmt) TestRunStarted() {
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.lock.Unlock()
|
||||||
|
@ -255,8 +200,6 @@ func (f *basefmt) Feature(ft *messages.GherkinDocument, p string, c []byte) {
|
||||||
defer f.lock.Unlock()
|
defer f.lock.Unlock()
|
||||||
|
|
||||||
*f.firstFeature = false
|
*f.firstFeature = false
|
||||||
|
|
||||||
f.features = append(f.features, &feature{GherkinDocument: ft, time: timeNowFunc()})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *basefmt) Passed(pickle *messages.Pickle, step *messages.Pickle_PickleStep, match *StepDefinition) {
|
func (f *basefmt) Passed(pickle *messages.Pickle, step *messages.Pickle_PickleStep, match *StepDefinition) {
|
||||||
|
@ -383,13 +326,7 @@ func (f *basefmt) Sync(cf ConcurrentFormatter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *basefmt) Copy(cf ConcurrentFormatter) {
|
func (f *basefmt) Copy(cf ConcurrentFormatter) {}
|
||||||
if source, ok := cf.(*basefmt); ok {
|
|
||||||
for _, v := range source.features {
|
|
||||||
f.features = append(f.features, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *basefmt) snippets() string {
|
func (f *basefmt) snippets() string {
|
||||||
undefinedStepResults := f.storage.mustGetPickleStepResultsByStatus(undefined)
|
undefinedStepResults := f.storage.mustGetPickleStepResultsByStatus(undefined)
|
||||||
|
|
|
@ -34,7 +34,9 @@ type cukefmt struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) Summary() {
|
func (f *cukefmt) Summary() {
|
||||||
res := f.buildCukeFeatures(f.features)
|
features := f.storage.mustGetFeatures()
|
||||||
|
|
||||||
|
res := f.buildCukeFeatures(features)
|
||||||
|
|
||||||
dat, err := json.MarshalIndent(res, "", " ")
|
dat, err := json.MarshalIndent(res, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,7 +59,7 @@ func (f *cukefmt) Copy(cf ConcurrentFormatter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeFeatures(features []*feature) (res []cukeFeatureJSON) {
|
func (f *cukefmt) buildCukeFeatures(features []*feature) (res []cukeFeatureJSON) {
|
||||||
sort.Sort(sortByName(features))
|
sort.Sort(sortFeaturesByName(features))
|
||||||
|
|
||||||
res = make([]cukeFeatureJSON, len(features))
|
res = make([]cukeFeatureJSON, len(features))
|
||||||
|
|
||||||
|
@ -88,7 +90,7 @@ func (f *cukefmt) buildCukeElements(pickles []*messages.Pickle) (res []cukeEleme
|
||||||
pickleResult := f.storage.mustGetPickleResult(pickle.Id)
|
pickleResult := f.storage.mustGetPickleResult(pickle.Id)
|
||||||
pickleStepResults := f.storage.mustGetPickleStepResultsByPickleID(pickle.Id)
|
pickleStepResults := f.storage.mustGetPickleStepResultsByPickleID(pickle.Id)
|
||||||
|
|
||||||
cukeElement := f.buildCukeElement(pickle.Name, pickle.AstNodeIds)
|
cukeElement := f.buildCukeElement(pickle)
|
||||||
|
|
||||||
stepStartedAt := pickleResult.StartedAt
|
stepStartedAt := pickleResult.StartedAt
|
||||||
|
|
||||||
|
@ -204,10 +206,11 @@ func buildCukeFeature(feat *feature) cukeFeatureJSON {
|
||||||
return cukeFeature
|
return cukeFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeElement(pickleName string, pickleAstNodeIDs []string) (cukeElement cukeElement) {
|
func (f *cukefmt) buildCukeElement(pickle *messages.Pickle) (cukeElement cukeElement) {
|
||||||
scenario := f.findScenario(pickleAstNodeIDs[0])
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
|
scenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
cukeElement.Name = pickleName
|
cukeElement.Name = pickle.Name
|
||||||
cukeElement.Line = int(scenario.Location.Line)
|
cukeElement.Line = int(scenario.Location.Line)
|
||||||
cukeElement.Description = scenario.Description
|
cukeElement.Description = scenario.Description
|
||||||
cukeElement.Keyword = scenario.Keyword
|
cukeElement.Keyword = scenario.Keyword
|
||||||
|
@ -219,11 +222,11 @@ func (f *cukefmt) buildCukeElement(pickleName string, pickleAstNodeIDs []string)
|
||||||
cukeElement.Tags[idx].Name = element.Name
|
cukeElement.Tags[idx].Name = element.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pickleAstNodeIDs) == 1 {
|
if len(pickle.AstNodeIds) == 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
example, _ := f.findExample(pickleAstNodeIDs[1])
|
example, _ := feature.findExample(pickle.AstNodeIds[1])
|
||||||
|
|
||||||
for _, tag := range example.Tags {
|
for _, tag := range example.Tags {
|
||||||
tag := cukeTag{Line: int(tag.Location.Line), Name: tag.Name}
|
tag := cukeTag{Line: int(tag.Location.Line), Name: tag.Name}
|
||||||
|
@ -232,7 +235,7 @@ func (f *cukefmt) buildCukeElement(pickleName string, pickleAstNodeIDs []string)
|
||||||
|
|
||||||
examples := scenario.GetExamples()
|
examples := scenario.GetExamples()
|
||||||
if len(examples) > 0 {
|
if len(examples) > 0 {
|
||||||
rowID := pickleAstNodeIDs[1]
|
rowID := pickle.AstNodeIds[1]
|
||||||
|
|
||||||
for _, example := range examples {
|
for _, example := range examples {
|
||||||
for idx, row := range example.TableBody {
|
for idx, row := range example.TableBody {
|
||||||
|
@ -248,12 +251,13 @@ func (f *cukefmt) buildCukeElement(pickleName string, pickleAstNodeIDs []string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeStep(pickle *messages.Pickle, stepResult pickleStepResult) (cukeStep cukeStep) {
|
func (f *cukefmt) buildCukeStep(pickle *messages.Pickle, stepResult pickleStepResult) (cukeStep cukeStep) {
|
||||||
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
pickleStep := f.storage.mustGetPickleStep(stepResult.PickleStepID)
|
pickleStep := f.storage.mustGetPickleStep(stepResult.PickleStepID)
|
||||||
step := f.findStep(pickleStep.AstNodeIds[0])
|
step := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
line := step.Location.Line
|
line := step.Location.Line
|
||||||
if len(pickle.AstNodeIds) == 2 {
|
if len(pickle.AstNodeIds) == 2 {
|
||||||
_, row := f.findExample(pickle.AstNodeIds[1])
|
_, row := feature.findExample(pickle.AstNodeIds[1])
|
||||||
line = row.Location.Line
|
line = row.Location.Line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,8 +149,9 @@ func (f *events) Copy(cf ConcurrentFormatter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *events) step(pickle *messages.Pickle, pickleStep *messages.Pickle_PickleStep) {
|
func (f *events) step(pickle *messages.Pickle, pickleStep *messages.Pickle_PickleStep) {
|
||||||
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
pickleStepResult := f.storage.mustGetPickleStepResult(pickleStep.Id)
|
pickleStepResult := f.storage.mustGetPickleStepResult(pickleStep.Id)
|
||||||
step := f.findStep(pickleStep.AstNodeIds[0])
|
step := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
var errMsg string
|
var errMsg string
|
||||||
if pickleStepResult.err != nil {
|
if pickleStepResult.err != nil {
|
||||||
|
@ -207,7 +208,8 @@ func (f *events) Defined(pickle *messages.Pickle, pickleStep *messages.Pickle_Pi
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.lock.Unlock()
|
||||||
|
|
||||||
step := f.findStep(pickleStep.AstNodeIds[0])
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
|
step := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
if def != nil {
|
if def != nil {
|
||||||
m := def.Expr.FindStringSubmatchIndex(pickleStep.Text)[2:]
|
m := def.Expr.FindStringSubmatchIndex(pickleStep.Text)[2:]
|
||||||
|
@ -294,10 +296,12 @@ func (f *events) Pending(pickle *messages.Pickle, step *messages.Pickle_PickleSt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *events) scenarioLocation(pickle *messages.Pickle) string {
|
func (f *events) scenarioLocation(pickle *messages.Pickle) string {
|
||||||
scenario := f.findScenario(pickle.AstNodeIds[0])
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
|
scenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
line := scenario.Location.Line
|
line := scenario.Location.Line
|
||||||
if len(pickle.AstNodeIds) == 2 {
|
if len(pickle.AstNodeIds) == 2 {
|
||||||
_, row := f.findExample(pickle.AstNodeIds[1])
|
_, row := feature.findExample(pickle.AstNodeIds[1])
|
||||||
line = row.Location.Line
|
line = row.Location.Line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
fmt_junit.go
17
fmt_junit.go
|
@ -54,19 +54,20 @@ func junitTimeDuration(from, to time.Time) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *junitFormatter) buildJUNITPackageSuite() junitPackageSuite {
|
func (f *junitFormatter) buildJUNITPackageSuite() junitPackageSuite {
|
||||||
|
features := f.storage.mustGetFeatures()
|
||||||
|
sort.Sort(sortFeaturesByName(features))
|
||||||
|
|
||||||
suite := junitPackageSuite{
|
suite := junitPackageSuite{
|
||||||
Name: f.suiteName,
|
Name: f.suiteName,
|
||||||
TestSuites: make([]*junitTestSuite, len(f.features)),
|
TestSuites: make([]*junitTestSuite, len(features)),
|
||||||
Time: junitTimeDuration(f.startedAt, timeNowFunc()),
|
Time: junitTimeDuration(f.startedAt, timeNowFunc()),
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(sortByName(f.features))
|
for idx, feature := range features {
|
||||||
|
pickles := f.storage.mustGetPickles(feature.Uri)
|
||||||
for idx, feat := range f.features {
|
|
||||||
pickles := f.storage.mustGetPickles(feat.Uri)
|
|
||||||
sort.Sort(sortPicklesByID(pickles))
|
sort.Sort(sortPicklesByID(pickles))
|
||||||
|
|
||||||
var finishedAt = feat.startedAt()
|
var finishedAt = feature.startedAt()
|
||||||
|
|
||||||
if len(pickles) > 0 {
|
if len(pickles) > 0 {
|
||||||
lastPickle := pickles[len(pickles)-1]
|
lastPickle := pickles[len(pickles)-1]
|
||||||
|
@ -79,8 +80,8 @@ func (f *junitFormatter) buildJUNITPackageSuite() junitPackageSuite {
|
||||||
}
|
}
|
||||||
|
|
||||||
ts := junitTestSuite{
|
ts := junitTestSuite{
|
||||||
Name: feat.GherkinDocument.Feature.Name,
|
Name: feature.Feature.Name,
|
||||||
Time: junitTimeDuration(feat.startedAt(), finishedAt),
|
Time: junitTimeDuration(feature.startedAt(), finishedAt),
|
||||||
TestCases: make([]*junitTestCase, len(pickles)),
|
TestCases: make([]*junitTestCase, len(pickles)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,9 +130,10 @@ func keywordAndName(keyword, name string) string {
|
||||||
return title
|
return title
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) scenarioLengths(scenarioAstID string) (scenarioHeaderLength int, maxLength int) {
|
func (f *pretty) scenarioLengths(pickle *messages.Pickle) (scenarioHeaderLength int, maxLength int) {
|
||||||
astScenario := f.findScenario(scenarioAstID)
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
astBackground := f.findBackground(scenarioAstID)
|
astScenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
astBackground := feature.findBackground(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
scenarioHeaderLength = f.lengthPickle(astScenario.Keyword, astScenario.Name)
|
scenarioHeaderLength = f.lengthPickle(astScenario.Keyword, astScenario.Name)
|
||||||
maxLength = f.longestStep(astScenario.Steps, scenarioHeaderLength)
|
maxLength = f.longestStep(astScenario.Steps, scenarioHeaderLength)
|
||||||
|
@ -144,17 +145,19 @@ func (f *pretty) scenarioLengths(scenarioAstID string) (scenarioHeaderLength int
|
||||||
return scenarioHeaderLength, maxLength
|
return scenarioHeaderLength, maxLength
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printScenarioHeader(astScenario *messages.GherkinDocument_Feature_Scenario, spaceFilling int) {
|
func (f *pretty) printScenarioHeader(pickle *messages.Pickle, astScenario *messages.GherkinDocument_Feature_Scenario, spaceFilling int) {
|
||||||
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
text := s(f.indent) + keywordAndName(astScenario.Keyword, astScenario.Name)
|
text := s(f.indent) + keywordAndName(astScenario.Keyword, astScenario.Name)
|
||||||
text += s(spaceFilling) + f.line(f.lastFeature().Uri, astScenario.Location)
|
text += s(spaceFilling) + line(feature.Uri, astScenario.Location)
|
||||||
fmt.Fprintln(f.out, "\n"+text)
|
fmt.Fprintln(f.out, "\n"+text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
func (f *pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
||||||
astScenario := f.findScenario(pickle.AstNodeIds[0])
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
astBackground := f.findBackground(pickle.AstNodeIds[0])
|
astScenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
astBackground := feature.findBackground(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle.AstNodeIds[0])
|
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||||
|
|
||||||
if astBackground != nil {
|
if astBackground != nil {
|
||||||
fmt.Fprintln(f.out, "\n"+s(f.indent)+keywordAndName(astBackground.Keyword, astBackground.Name))
|
fmt.Fprintln(f.out, "\n"+s(f.indent)+keywordAndName(astBackground.Keyword, astBackground.Name))
|
||||||
|
@ -166,7 +169,7 @@ func (f *pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
||||||
|
|
||||||
// do not print scenario headers and examples multiple times
|
// do not print scenario headers and examples multiple times
|
||||||
if len(astScenario.Examples) > 0 {
|
if len(astScenario.Examples) > 0 {
|
||||||
exampleTable, exampleRow := f.findExample(pickle.AstNodeIds[1])
|
exampleTable, exampleRow := feature.findExample(pickle.AstNodeIds[1])
|
||||||
firstExampleRow := exampleTable.TableBody[0].Id == exampleRow.Id
|
firstExampleRow := exampleTable.TableBody[0].Id == exampleRow.Id
|
||||||
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
||||||
|
|
||||||
|
@ -175,7 +178,7 @@ func (f *pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.printScenarioHeader(astScenario, maxLength-scenarioHeaderLength)
|
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||||
|
|
||||||
for _, examples := range astScenario.Examples {
|
for _, examples := range astScenario.Examples {
|
||||||
max := longestExampleRow(examples, cyan, cyan)
|
max := longestExampleRow(examples, cyan, cyan)
|
||||||
|
@ -202,17 +205,16 @@ func (f *pretty) Summary() {
|
||||||
for _, fail := range failedStepResults {
|
for _, fail := range failedStepResults {
|
||||||
pickle := f.storage.mustGetPickle(fail.PickleID)
|
pickle := f.storage.mustGetPickle(fail.PickleID)
|
||||||
pickleStep := f.storage.mustGetPickleStep(fail.PickleStepID)
|
pickleStep := f.storage.mustGetPickleStep(fail.PickleStepID)
|
||||||
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
|
|
||||||
feature := f.findFeature(pickle.AstNodeIds[0])
|
astScenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
astScenario := f.findScenario(pickle.AstNodeIds[0])
|
|
||||||
scenarioDesc := fmt.Sprintf("%s: %s", astScenario.Keyword, pickle.Name)
|
scenarioDesc := fmt.Sprintf("%s: %s", astScenario.Keyword, pickle.Name)
|
||||||
|
|
||||||
astStep := f.findStep(pickleStep.AstNodeIds[0])
|
astStep := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
stepDesc := strings.TrimSpace(astStep.Keyword) + " " + pickleStep.Text
|
stepDesc := strings.TrimSpace(astStep.Keyword) + " " + pickleStep.Text
|
||||||
|
|
||||||
fmt.Fprintln(f.out, s(f.indent)+red(scenarioDesc)+f.line(feature.Uri, astScenario.Location))
|
fmt.Fprintln(f.out, s(f.indent)+red(scenarioDesc)+line(feature.Uri, astScenario.Location))
|
||||||
fmt.Fprintln(f.out, s(f.indent*2)+red(stepDesc)+f.line(feature.Uri, astStep.Location))
|
fmt.Fprintln(f.out, s(f.indent*2)+red(stepDesc)+line(feature.Uri, astStep.Location))
|
||||||
fmt.Fprintln(f.out, s(f.indent*3)+red("Error: ")+redb(fmt.Sprintf("%+v", fail.err))+"\n")
|
fmt.Fprintln(f.out, s(f.indent*3)+red("Error: ")+redb(fmt.Sprintf("%+v", fail.err))+"\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,10 +226,11 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
var errorMsg string
|
var errorMsg string
|
||||||
var clr = green
|
var clr = green
|
||||||
|
|
||||||
astScenario := f.findScenario(pickle.AstNodeIds[0])
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle.AstNodeIds[0])
|
astScenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||||
|
|
||||||
exampleTable, exampleRow := f.findExample(pickle.AstNodeIds[1])
|
exampleTable, exampleRow := feature.findExample(pickle.AstNodeIds[1])
|
||||||
printExampleHeader := exampleTable.TableBody[0].Id == exampleRow.Id
|
printExampleHeader := exampleTable.TableBody[0].Id == exampleRow.Id
|
||||||
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
||||||
|
|
||||||
|
@ -235,7 +238,7 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
|
|
||||||
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
||||||
if firstExamplesTable && printExampleHeader && firstExecutedScenarioStep {
|
if firstExamplesTable && printExampleHeader && firstExecutedScenarioStep {
|
||||||
f.printScenarioHeader(astScenario, maxLength-scenarioHeaderLength)
|
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(exampleTable.TableBody) == 0 {
|
if len(exampleTable.TableBody) == 0 {
|
||||||
|
@ -265,7 +268,7 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
// in first example, we need to print steps
|
// in first example, we need to print steps
|
||||||
|
|
||||||
pickleStep := f.storage.mustGetPickleStep(result.PickleStepID)
|
pickleStep := f.storage.mustGetPickleStep(result.PickleStepID)
|
||||||
astStep := f.findStep(pickleStep.AstNodeIds[0])
|
astStep := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
var text = ""
|
var text = ""
|
||||||
if result.def != nil {
|
if result.def != nil {
|
||||||
|
@ -282,7 +285,7 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
text = cyan(astStep.Text)
|
text = cyan(astStep.Text)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, maxLength := f.scenarioLengths(pickle.AstNodeIds[0])
|
_, maxLength := f.scenarioLengths(pickle)
|
||||||
stepLength := f.lengthPickleStep(astStep.Keyword, astStep.Text)
|
stepLength := f.lengthPickleStep(astStep.Keyword, astStep.Text)
|
||||||
|
|
||||||
text += s(maxLength - stepLength)
|
text += s(maxLength - stepLength)
|
||||||
|
@ -336,9 +339,10 @@ func (f *pretty) printTableHeader(row *messages.GherkinDocument_Feature_TableRow
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printStep(pickle *messages.Pickle, pickleStep *messages.Pickle_PickleStep) {
|
func (f *pretty) printStep(pickle *messages.Pickle, pickleStep *messages.Pickle_PickleStep) {
|
||||||
astBackground := f.findBackground(pickle.AstNodeIds[0])
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
astScenario := f.findScenario(pickle.AstNodeIds[0])
|
astBackground := feature.findBackground(pickle.AstNodeIds[0])
|
||||||
astStep := f.findStep(pickleStep.AstNodeIds[0])
|
astScenario := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
|
astStep := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
var backgroundSteps int
|
var backgroundSteps int
|
||||||
if astBackground != nil {
|
if astBackground != nil {
|
||||||
|
@ -374,12 +378,12 @@ func (f *pretty) printStep(pickle *messages.Pickle, pickleStep *messages.Pickle_
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle.AstNodeIds[0])
|
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||||
stepLength := f.lengthPickleStep(astStep.Keyword, pickleStep.Text)
|
stepLength := f.lengthPickleStep(astStep.Keyword, pickleStep.Text)
|
||||||
|
|
||||||
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
||||||
if !astBackgroundStep && firstExecutedScenarioStep {
|
if !astBackgroundStep && firstExecutedScenarioStep {
|
||||||
f.printScenarioHeader(astScenario, maxLength-scenarioHeaderLength)
|
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
pickleStepResult := f.storage.mustGetPickleStepResult(pickleStep.Id)
|
pickleStepResult := f.storage.mustGetPickleStepResult(pickleStep.Id)
|
||||||
|
@ -519,7 +523,7 @@ func (f *pretty) longestStep(steps []*messages.GherkinDocument_Feature_Step, pic
|
||||||
}
|
}
|
||||||
|
|
||||||
// a line number representation in feature file
|
// a line number representation in feature file
|
||||||
func (f *pretty) line(path string, loc *messages.Location) string {
|
func line(path string, loc *messages.Location) string {
|
||||||
return " " + blackb(fmt.Sprintf("# %s:%d", path, loc.Line))
|
return " " + blackb(fmt.Sprintf("# %s:%d", path, loc.Line))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,12 +48,13 @@ func (f *progress) Summary() {
|
||||||
if sr.Status == failed {
|
if sr.Status == failed {
|
||||||
pickle := f.storage.mustGetPickle(sr.PickleID)
|
pickle := f.storage.mustGetPickle(sr.PickleID)
|
||||||
pickleStep := f.storage.mustGetPickleStep(sr.PickleStepID)
|
pickleStep := f.storage.mustGetPickleStep(sr.PickleStepID)
|
||||||
|
feature := f.storage.mustGetFeature(pickle.Uri)
|
||||||
|
|
||||||
sc := f.findScenario(pickle.AstNodeIds[0])
|
sc := feature.findScenario(pickle.AstNodeIds[0])
|
||||||
scenarioDesc := fmt.Sprintf("%s: %s", sc.Keyword, pickle.Name)
|
scenarioDesc := fmt.Sprintf("%s: %s", sc.Keyword, pickle.Name)
|
||||||
scenarioLine := fmt.Sprintf("%s:%d", pickle.Uri, sc.Location.Line)
|
scenarioLine := fmt.Sprintf("%s:%d", pickle.Uri, sc.Location.Line)
|
||||||
|
|
||||||
step := f.findStep(pickleStep.AstNodeIds[0])
|
step := feature.findStep(pickleStep.AstNodeIds[0])
|
||||||
stepDesc := strings.TrimSpace(step.Keyword) + " " + pickleStep.Text
|
stepDesc := strings.TrimSpace(step.Keyword) + " " + pickleStep.Text
|
||||||
stepLine := fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line)
|
stepLine := fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line)
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,15 @@ func TestProgressFormatterWhenStepPanics(t *testing.T) {
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
w := colors.Uncolored(&buf)
|
w := colors.Uncolored(&buf)
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", w),
|
fmt: progressFunc("progress", w),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^one$`, func() error { return nil })
|
s.Step(`^one$`, func() error { return nil })
|
||||||
s.Step(`^two$`, func() error { panic("omg") })
|
s.Step(`^two$`, func() error { panic("omg") })
|
||||||
|
@ -41,7 +43,8 @@ func TestProgressFormatterWhenStepPanics(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +52,7 @@ func TestProgressFormatterWhenStepPanics(t *testing.T) {
|
||||||
require.True(t, failed)
|
require.True(t, failed)
|
||||||
|
|
||||||
actual := buf.String()
|
actual := buf.String()
|
||||||
assert.Contains(t, actual, "godog/fmt_progress_test.go:39")
|
assert.Contains(t, actual, "godog/fmt_progress_test.go:41")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestProgressFormatterWithPanicInMultistep(t *testing.T) {
|
func TestProgressFormatterWithPanicInMultistep(t *testing.T) {
|
||||||
|
@ -58,13 +61,15 @@ func TestProgressFormatterWithPanicInMultistep(t *testing.T) {
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
w := colors.Uncolored(&buf)
|
w := colors.Uncolored(&buf)
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", w),
|
fmt: progressFunc("progress", w),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^sub1$`, func() error { return nil })
|
s.Step(`^sub1$`, func() error { return nil })
|
||||||
s.Step(`^sub-sub$`, func() error { return nil })
|
s.Step(`^sub-sub$`, func() error { return nil })
|
||||||
|
@ -75,7 +80,8 @@ func TestProgressFormatterWithPanicInMultistep(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,13 +95,15 @@ func TestProgressFormatterMultistepTemplates(t *testing.T) {
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
w := colors.Uncolored(&buf)
|
w := colors.Uncolored(&buf)
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", w),
|
fmt: progressFunc("progress", w),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^sub-sub$`, func() error { return nil })
|
s.Step(`^sub-sub$`, func() error { return nil })
|
||||||
s.Step(`^substep$`, func() Steps { return Steps{"sub-sub", `unavailable "John" cost 5`, "one", "three"} })
|
s.Step(`^substep$`, func() Steps { return Steps{"sub-sub", `unavailable "John" cost 5`, "one", "three"} })
|
||||||
|
@ -105,7 +113,8 @@ func TestProgressFormatterMultistepTemplates(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +171,15 @@ Feature: basic
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(featureSource), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(featureSource), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
w := colors.Uncolored(&buf)
|
w := colors.Uncolored(&buf)
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", w),
|
fmt: progressFunc("progress", w),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^one$`, func() error { return nil })
|
s.Step(`^one$`, func() error { return nil })
|
||||||
s.Step(`^two:$`, func(doc *messages.PickleStepArgument_PickleDocString) Steps { return Steps{"one"} })
|
s.Step(`^two:$`, func(doc *messages.PickleStepArgument_PickleDocString) Steps { return Steps{"one"} })
|
||||||
|
@ -176,7 +187,8 @@ Feature: basic
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +209,9 @@ Feature: basic
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(featureSource), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(featureSource), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
var subStep = `three:
|
var subStep = `three:
|
||||||
"""
|
"""
|
||||||
|
@ -208,7 +222,7 @@ Feature: basic
|
||||||
w := colors.Uncolored(&buf)
|
w := colors.Uncolored(&buf)
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", w),
|
fmt: progressFunc("progress", w),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^one$`, func() error { return nil })
|
s.Step(`^one$`, func() error { return nil })
|
||||||
s.Step(`^two$`, func() Steps { return Steps{subStep} })
|
s.Step(`^two$`, func() Steps { return Steps{subStep} })
|
||||||
|
@ -217,7 +231,8 @@ Feature: basic
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
run.go
2
run.go
|
@ -237,6 +237,8 @@ func runWithOptions(suite string, runner runner, opt Options) int {
|
||||||
|
|
||||||
runner.storage = newStorage()
|
runner.storage = newStorage()
|
||||||
for _, feat := range runner.features {
|
for _, feat := range runner.features {
|
||||||
|
runner.storage.mustInsertFeature(feat)
|
||||||
|
|
||||||
for _, pickle := range feat.pickles {
|
for _, pickle := range feat.pickles {
|
||||||
runner.storage.mustInsertPickle(pickle)
|
runner.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
27
run_test.go
27
run_test.go
|
@ -64,11 +64,13 @@ func TestFailsOrPassesBasedOnStrictModeWhenHasPendingSteps(t *testing.T) {
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", ioutil.Discard),
|
fmt: progressFunc("progress", ioutil.Discard),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^one$`, func() error { return nil })
|
s.Step(`^one$`, func() error { return nil })
|
||||||
s.Step(`^two$`, func() error { return ErrPending })
|
s.Step(`^two$`, func() error { return ErrPending })
|
||||||
|
@ -76,7 +78,8 @@ func TestFailsOrPassesBasedOnStrictModeWhenHasPendingSteps(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,11 +97,13 @@ func TestFailsOrPassesBasedOnStrictModeWhenHasUndefinedSteps(t *testing.T) {
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", ioutil.Discard),
|
fmt: progressFunc("progress", ioutil.Discard),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^one$`, func() error { return nil })
|
s.Step(`^one$`, func() error { return nil })
|
||||||
// two - is undefined
|
// two - is undefined
|
||||||
|
@ -106,7 +111,8 @@ func TestFailsOrPassesBasedOnStrictModeWhenHasUndefinedSteps(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +130,13 @@ func TestShouldFailOnError(t *testing.T) {
|
||||||
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
gd, err := gherkin.ParseGherkinDocument(strings.NewReader(basicGherkinFeature), (&messages.Incrementing{}).NewId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pickles := gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
gd.Uri = path
|
||||||
|
ft := feature{GherkinDocument: gd}
|
||||||
|
ft.pickles = gherkin.Pickles(*gd, path, (&messages.Incrementing{}).NewId)
|
||||||
|
|
||||||
r := runner{
|
r := runner{
|
||||||
fmt: progressFunc("progress", ioutil.Discard),
|
fmt: progressFunc("progress", ioutil.Discard),
|
||||||
features: []*feature{{GherkinDocument: gd, pickles: pickles}},
|
features: []*feature{&ft},
|
||||||
initializer: func(s *Suite) {
|
initializer: func(s *Suite) {
|
||||||
s.Step(`^one$`, func() error { return nil })
|
s.Step(`^one$`, func() error { return nil })
|
||||||
s.Step(`^two$`, func() error { return fmt.Errorf("error") })
|
s.Step(`^two$`, func() error { return fmt.Errorf("error") })
|
||||||
|
@ -136,7 +144,8 @@ func TestShouldFailOnError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.storage = newStorage()
|
r.storage = newStorage()
|
||||||
for _, pickle := range pickles {
|
r.storage.mustInsertFeature(&ft)
|
||||||
|
for _, pickle := range ft.pickles {
|
||||||
r.storage.mustInsertPickle(pickle)
|
r.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
180
storage.go
180
storage.go
|
@ -11,6 +11,9 @@ const (
|
||||||
writeMode bool = true
|
writeMode bool = true
|
||||||
readMode bool = false
|
readMode bool = false
|
||||||
|
|
||||||
|
tableFeature string = "feature"
|
||||||
|
tableFeatureIndexURI string = "id"
|
||||||
|
|
||||||
tablePickle string = "pickle"
|
tablePickle string = "pickle"
|
||||||
tablePickleIndexID string = "id"
|
tablePickleIndexID string = "id"
|
||||||
tablePickleIndexURI string = "uri"
|
tablePickleIndexURI string = "uri"
|
||||||
|
@ -35,6 +38,16 @@ func newStorage() *storage {
|
||||||
// Create the DB schema
|
// Create the DB schema
|
||||||
schema := memdb.DBSchema{
|
schema := memdb.DBSchema{
|
||||||
Tables: map[string]*memdb.TableSchema{
|
Tables: map[string]*memdb.TableSchema{
|
||||||
|
tableFeature: {
|
||||||
|
Name: tableFeature,
|
||||||
|
Indexes: map[string]*memdb.IndexSchema{
|
||||||
|
tableFeatureIndexURI: {
|
||||||
|
Name: tableFeatureIndexURI,
|
||||||
|
Unique: true,
|
||||||
|
Indexer: &memdb.StringFieldIndex{Field: "Uri"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
tablePickle: {
|
tablePickle: {
|
||||||
Name: tablePickle,
|
Name: tablePickle,
|
||||||
Indexes: map[string]*memdb.IndexSchema{
|
Indexes: map[string]*memdb.IndexSchema{
|
||||||
|
@ -119,29 +132,12 @@ func (s *storage) mustInsertPickle(p *messages.Pickle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickle(id string) *messages.Pickle {
|
func (s *storage) mustGetPickle(id string) *messages.Pickle {
|
||||||
txn := s.db.Txn(readMode)
|
v := s.mustFirst(tablePickle, tablePickleIndexID, id)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
var v interface{}
|
|
||||||
v, err := txn.First(tablePickle, tablePickleIndexID, id)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else if v == nil {
|
|
||||||
panic("Couldn't find pickle with ID: " + id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.(*messages.Pickle)
|
return v.(*messages.Pickle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickles(uri string) (ps []*messages.Pickle) {
|
func (s *storage) mustGetPickles(uri string) (ps []*messages.Pickle) {
|
||||||
txn := s.db.Txn(readMode)
|
it := s.mustGet(tablePickle, tablePickleIndexURI, uri)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
it, err := txn.Get(tablePickle, tablePickleIndexURI, uri)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for v := it.Next(); v != nil; v = it.Next() {
|
for v := it.Next(); v != nil; v = it.Next() {
|
||||||
ps = append(ps, v.(*messages.Pickle))
|
ps = append(ps, v.(*messages.Pickle))
|
||||||
}
|
}
|
||||||
|
@ -150,73 +146,34 @@ func (s *storage) mustGetPickles(uri string) (ps []*messages.Pickle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickleStep(id string) *messages.Pickle_PickleStep {
|
func (s *storage) mustGetPickleStep(id string) *messages.Pickle_PickleStep {
|
||||||
txn := s.db.Txn(readMode)
|
v := s.mustFirst(tablePickleStep, tablePickleStepIndexID, id)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
var v interface{}
|
|
||||||
v, err := txn.First(tablePickleStep, tablePickleStepIndexID, id)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else if v == nil {
|
|
||||||
panic("Couldn't find pickle step with ID: " + id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.(*messages.Pickle_PickleStep)
|
return v.(*messages.Pickle_PickleStep)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustInsertPickleResult(pr pickleResult) {
|
func (s *storage) mustInsertPickleResult(pr pickleResult) {
|
||||||
txn := s.db.Txn(writeMode)
|
s.mustInsert(tablePickleResult, pr)
|
||||||
|
|
||||||
if err := txn.Insert(tablePickleResult, pr); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
txn.Commit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustInsertPickleStepResult(psr pickleStepResult) {
|
func (s *storage) mustInsertPickleStepResult(psr pickleStepResult) {
|
||||||
txn := s.db.Txn(writeMode)
|
s.mustInsert(tablePickleStepResult, psr)
|
||||||
|
|
||||||
if err := txn.Insert(tablePickleStepResult, psr); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
txn.Commit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickleResult(id string) pickleResult {
|
func (s *storage) mustGetPickleResult(id string) pickleResult {
|
||||||
pr, err := s.getPickleResult(id)
|
v := s.mustFirst(tablePickleResult, tablePickleResultIndexPickleID, id)
|
||||||
if err != nil {
|
return v.(pickleResult)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) getPickleResult(id string) (_ pickleResult, err error) {
|
func (s *storage) getPickleResult(id string) (_ pickleResult, err error) {
|
||||||
txn := s.db.Txn(readMode)
|
v, err := s.first(tablePickleResult, tablePickleResultIndexPickleID, id)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
v, err := txn.First(tablePickleResult, tablePickleResultIndexPickleID, id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
} else if v == nil {
|
|
||||||
err = fmt.Errorf("Couldn't find pickle result with ID: %s", id)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.(pickleResult), nil
|
return v.(pickleResult), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickleResults() (prs []pickleResult) {
|
func (s *storage) mustGetPickleResults() (prs []pickleResult) {
|
||||||
txn := s.db.Txn(readMode)
|
it := s.mustGet(tablePickleResult, tablePickleResultIndexPickleID)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
it, err := txn.Get(tablePickleResult, tablePickleResultIndexPickleID)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for v := it.Next(); v != nil; v = it.Next() {
|
for v := it.Next(); v != nil; v = it.Next() {
|
||||||
prs = append(prs, v.(pickleResult))
|
prs = append(prs, v.(pickleResult))
|
||||||
}
|
}
|
||||||
|
@ -225,28 +182,12 @@ func (s *storage) mustGetPickleResults() (prs []pickleResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickleStepResult(id string) pickleStepResult {
|
func (s *storage) mustGetPickleStepResult(id string) pickleStepResult {
|
||||||
txn := s.db.Txn(readMode)
|
v := s.mustFirst(tablePickleStepResult, tablePickleStepResultIndexPickleStepID, id)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
v, err := txn.First(tablePickleStepResult, tablePickleStepResultIndexPickleStepID, id)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else if v == nil {
|
|
||||||
panic("Couldn't find pickle step result with ID: " + id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.(pickleStepResult)
|
return v.(pickleStepResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickleStepResultsByPickleID(pickleID string) (psrs []pickleStepResult) {
|
func (s *storage) mustGetPickleStepResultsByPickleID(pickleID string) (psrs []pickleStepResult) {
|
||||||
txn := s.db.Txn(readMode)
|
it := s.mustGet(tablePickleStepResult, tablePickleStepResultIndexPickleID, pickleID)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
it, err := txn.Get(tablePickleStepResult, tablePickleStepResultIndexPickleID, pickleID)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for v := it.Next(); v != nil; v = it.Next() {
|
for v := it.Next(); v != nil; v = it.Next() {
|
||||||
psrs = append(psrs, v.(pickleStepResult))
|
psrs = append(psrs, v.(pickleStepResult))
|
||||||
}
|
}
|
||||||
|
@ -255,17 +196,74 @@ func (s *storage) mustGetPickleStepResultsByPickleID(pickleID string) (psrs []pi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) mustGetPickleStepResultsByStatus(status stepResultStatus) (psrs []pickleStepResult) {
|
func (s *storage) mustGetPickleStepResultsByStatus(status stepResultStatus) (psrs []pickleStepResult) {
|
||||||
txn := s.db.Txn(readMode)
|
it := s.mustGet(tablePickleStepResult, tablePickleStepResultIndexStatus, status)
|
||||||
defer txn.Abort()
|
|
||||||
|
|
||||||
it, err := txn.Get(tablePickleStepResult, tablePickleStepResultIndexStatus, status)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for v := it.Next(); v != nil; v = it.Next() {
|
for v := it.Next(); v != nil; v = it.Next() {
|
||||||
psrs = append(psrs, v.(pickleStepResult))
|
psrs = append(psrs, v.(pickleStepResult))
|
||||||
}
|
}
|
||||||
|
|
||||||
return psrs
|
return psrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *storage) mustInsertFeature(f *feature) {
|
||||||
|
s.mustInsert(tableFeature, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) mustGetFeature(uri string) *feature {
|
||||||
|
v := s.mustFirst(tableFeature, tableFeatureIndexURI, uri)
|
||||||
|
return v.(*feature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) mustGetFeatures() (fs []*feature) {
|
||||||
|
it := s.mustGet(tableFeature, tableFeatureIndexURI)
|
||||||
|
for v := it.Next(); v != nil; v = it.Next() {
|
||||||
|
fs = append(fs, v.(*feature))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) mustInsert(table string, obj interface{}) {
|
||||||
|
txn := s.db.Txn(writeMode)
|
||||||
|
|
||||||
|
if err := txn.Insert(table, obj); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txn.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) first(table, index string, args ...interface{}) (v interface{}, err error) {
|
||||||
|
txn := s.db.Txn(readMode)
|
||||||
|
defer txn.Abort()
|
||||||
|
|
||||||
|
v, err = txn.First(table, index, args...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
} else if v == nil {
|
||||||
|
err = fmt.Errorf("Couldn't find index: %q in table: %q with args: %+v", index, table, args)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) mustFirst(table, index string, args ...interface{}) interface{} {
|
||||||
|
v, err := s.first(table, index, args...)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) mustGet(table, index string, args ...interface{}) memdb.ResultIterator {
|
||||||
|
txn := s.db.Txn(readMode)
|
||||||
|
defer txn.Abort()
|
||||||
|
|
||||||
|
it, err := txn.Get(table, index, args...)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
8
suite.go
8
suite.go
|
@ -98,11 +98,11 @@ func (f feature) startedAt() time.Time {
|
||||||
return f.time
|
return f.time
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortByName []*feature
|
type sortFeaturesByName []*feature
|
||||||
|
|
||||||
func (s sortByName) Len() int { return len(s) }
|
func (s sortFeaturesByName) Len() int { return len(s) }
|
||||||
func (s sortByName) Less(i, j int) bool { return s[i].Feature.Name < s[j].Feature.Name }
|
func (s sortFeaturesByName) Less(i, j int) bool { return s[i].Feature.Name < s[j].Feature.Name }
|
||||||
func (s sortByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
func (s sortFeaturesByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
||||||
type sortPicklesByID []*messages.Pickle
|
type sortPicklesByID []*messages.Pickle
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,8 @@ func (s *suiteContext) iRunFeatureSuiteWithTags(tags string) error {
|
||||||
|
|
||||||
s.testedSuite.storage = newStorage()
|
s.testedSuite.storage = newStorage()
|
||||||
for _, feat := range s.testedSuite.features {
|
for _, feat := range s.testedSuite.features {
|
||||||
|
s.testedSuite.storage.mustInsertFeature(feat)
|
||||||
|
|
||||||
for _, pickle := range feat.pickles {
|
for _, pickle := range feat.pickles {
|
||||||
s.testedSuite.storage.mustInsertPickle(pickle)
|
s.testedSuite.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
@ -212,6 +214,8 @@ func (s *suiteContext) iRunFeatureSuiteWithFormatter(name string) error {
|
||||||
|
|
||||||
s.testedSuite.storage = newStorage()
|
s.testedSuite.storage = newStorage()
|
||||||
for _, feat := range s.testedSuite.features {
|
for _, feat := range s.testedSuite.features {
|
||||||
|
s.testedSuite.storage.mustInsertFeature(feat)
|
||||||
|
|
||||||
for _, pickle := range feat.pickles {
|
for _, pickle := range feat.pickles {
|
||||||
s.testedSuite.storage.mustInsertPickle(pickle)
|
s.testedSuite.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,8 @@ func (tc *godogFeaturesScenario) iRunFeatureSuiteWithTags(tags string) error {
|
||||||
|
|
||||||
tc.testedSuite.storage = newStorage()
|
tc.testedSuite.storage = newStorage()
|
||||||
for _, feat := range tc.testedSuite.features {
|
for _, feat := range tc.testedSuite.features {
|
||||||
|
tc.testedSuite.storage.mustInsertFeature(feat)
|
||||||
|
|
||||||
for _, pickle := range feat.pickles {
|
for _, pickle := range feat.pickles {
|
||||||
tc.testedSuite.storage.mustInsertPickle(pickle)
|
tc.testedSuite.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
@ -174,6 +176,8 @@ func (tc *godogFeaturesScenario) iRunFeatureSuiteWithFormatter(name string) erro
|
||||||
|
|
||||||
tc.testedSuite.storage = newStorage()
|
tc.testedSuite.storage = newStorage()
|
||||||
for _, feat := range tc.testedSuite.features {
|
for _, feat := range tc.testedSuite.features {
|
||||||
|
tc.testedSuite.storage.mustInsertFeature(feat)
|
||||||
|
|
||||||
for _, pickle := range feat.pickles {
|
for _, pickle := range feat.pickles {
|
||||||
tc.testedSuite.storage.mustInsertPickle(pickle)
|
tc.testedSuite.storage.mustInsertPickle(pickle)
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче