Beispiel #1
0
func (r *runner) runAsync() (outcome types.SpecState, failure types.SpecFailure) {
	done := make(chan interface{}, 1)

	go func() {
		defer func() {
			if e := recover(); e != nil {
				r.failer.Panic(codelocation.New(2), e)
				select {
				case <-done:
					break
				default:
					close(done)
				}
			}
		}()

		r.asyncFunc(done)
	}()

	select {
	case <-done:
	case <-time.After(r.timeoutThreshold):
		r.failer.Timeout(r.codeLocation)
	}

	failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation)
	return
}
Beispiel #2
0
func InvalidSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType) {
	var (
		failer                *Failer.Failer
		componentCodeLocation types.CodeLocation
		innerCodeLocation     types.CodeLocation
	)

	BeforeEach(func() {
		failer = Failer.New()
		componentCodeLocation = codelocation.New(0)
		innerCodeLocation = codelocation.New(0)
	})

	Describe("invalid functions", func() {
		Context("when passed something that's not a function", func() {
			It("should panic", func() {
				Ω(func() {
					build("not a function", 0, failer, componentCodeLocation)
				}).Should(Panic())
			})
		})

		Context("when the function takes the wrong kind of argument", func() {
			It("should panic", func() {
				Ω(func() {
					build(func(oops string) {}, 0, failer, componentCodeLocation)
				}).Should(Panic())
			})
		})

		Context("when the function takes more than one argument", func() {
			It("should panic", func() {
				Ω(func() {
					build(func(done Done, oops string) {}, 0, failer, componentCodeLocation)
				}).Should(Panic())
			})
		})
	})
}
Beispiel #3
0
func (r *runner) runSync() (outcome types.SpecState, failure types.SpecFailure) {
	defer func() {
		if e := recover(); e != nil {
			r.failer.Panic(codelocation.New(2), e)
		}

		failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation)
	}()

	r.syncFunc()

	return
}
Beispiel #4
0
package leafnodes_test

import (
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo"
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/leafnodes"
	. "github.com/gocircuit/escher/github.com/onsi/gomega"

	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/codelocation"
	Failer "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/failer"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
	"time"
)

var _ = Describe("Measure Nodes", func() {
	It("should report the correct type, text, flag, and code location", func() {
		codeLocation := codelocation.New(0)
		measure := NewMeasureNode("my measure node", func(b Benchmarker) {}, types.FlagTypeFocused, codeLocation, 10, nil, 3)
		Ω(measure.Type()).Should(Equal(types.SpecComponentTypeMeasure))
		Ω(measure.Flag()).Should(Equal(types.FlagTypeFocused))
		Ω(measure.Text()).Should(Equal("my measure node"))
		Ω(measure.CodeLocation()).Should(Equal(codeLocation))
		Ω(measure.Samples()).Should(Equal(10))
	})

	Describe("benchmarking", func() {
		var measure *MeasureNode

		Describe("Value", func() {
			BeforeEach(func() {
				measure = NewMeasureNode("the measurement", func(b Benchmarker) {
					b.RecordValue("foo", 7, "info!")
					"##teamcity[testFinished name='A B C' duration='5000']" +
					"##teamcity[testSuiteFinished name='Foo|'s test suite']"
			Ω(actual).Should(Equal(expected))
		})
	})

	Describe("when the BeforeSuite fails", func() {
		var beforeSuite *types.SetupSummary

		BeforeEach(func() {
			beforeSuite = &types.SetupSummary{
				State:   types.SpecStateFailed,
				RunTime: 3 * time.Second,
				Failure: types.SpecFailure{
					Message:               "failed to setup\n",
					ComponentCodeLocation: codelocation.New(0),
				},
			}
			reporter.BeforeSuiteDidRun(beforeSuite)

			reporter.SpecSuiteDidEnd(&types.SuiteSummary{
				NumberOfSpecsThatWillBeRun: 1,
				NumberOfFailedSpecs:        1,
				RunTime:                    10 * time.Second,
			})
		})

		It("should record the test as having failed", func() {
			actual := buffer.String()
			expected := fmt.Sprintf(
				"##teamcity[testSuiteStarted name='Foo|'s test suite']"+
Beispiel #6
0
		reporter1 *reporters.FakeReporter
		reporter2 *reporters.FakeReporter
		failer    *Failer.Failer
		writer    *Writer.FakeGinkgoWriter

		thingsThatRan []string

		runner *SpecRunner
	)

	newBefSuite := func(text string, fail bool) leafnodes.SuiteNode {
		return leafnodes.NewBeforeSuiteNode(func() {
			writer.AddEvent(text)
			thingsThatRan = append(thingsThatRan, text)
			if fail {
				failer.Fail(text, codelocation.New(0))
			}
		}, codelocation.New(0), 0, failer)
	}

	newAftSuite := func(text string, fail bool) leafnodes.SuiteNode {
		return leafnodes.NewAfterSuiteNode(func() {
			writer.AddEvent(text)
			thingsThatRan = append(thingsThatRan, text)
			if fail {
				failer.Fail(text, codelocation.New(0))
			}
		}, codelocation.New(0), 0, failer)
	}

	newSpec := func(text string, flag types.FlagType, fail bool) *spec.Spec {
Beispiel #7
0
	Failer "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/failer"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
	"time"
)

var _ = Describe("SuiteNodes", func() {
	Describe("BeforeSuite nodes", func() {
		var befSuite SuiteNode
		var failer *Failer.Failer
		var codeLocation types.CodeLocation
		var innerCodeLocation types.CodeLocation
		var outcome bool

		BeforeEach(func() {
			failer = Failer.New()
			codeLocation = codelocation.New(0)
			innerCodeLocation = codelocation.New(0)
		})

		Context("when the body passes", func() {
			BeforeEach(func() {
				befSuite = NewBeforeSuiteNode(func() {
					time.Sleep(10 * time.Millisecond)
				}, codeLocation, 0, failer)
				outcome = befSuite.Run(0, 0, "")
			})

			It("should return true when run and report as passed", func() {
				Ω(outcome).Should(BeTrue())
				Ω(befSuite.Passed()).Should(BeTrue())
			})
Beispiel #8
0
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo"
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/spec"
	. "github.com/gocircuit/escher/github.com/onsi/gomega"

	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/codelocation"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/containernode"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/leafnodes"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
)

var _ = Describe("Specs", func() {
	var specs *Specs

	newSpec := func(text string, flag types.FlagType) *Spec {
		subject := leafnodes.NewItNode(text, func() {}, flag, codelocation.New(0), 0, nil, 0)
		return New(subject, []*containernode.ContainerNode{})
	}

	newMeasureSpec := func(text string, flag types.FlagType) *Spec {
		subject := leafnodes.NewMeasureNode(text, func(Benchmarker) {}, flag, codelocation.New(0), 0, nil, 0)
		return New(subject, []*containernode.ContainerNode{})
	}

	newSpecs := func(args ...interface{}) *Specs {
		specs := []*Spec{}
		for index := 0; index < len(args)-1; index += 2 {
			specs = append(specs, newSpec(args[index].(string), args[index+1].(types.FlagType)))
		}
		return NewSpecs(specs)
	}
Beispiel #9
0
		var f = func(runText string) func() {
			return func() {
				runOrder = append(runOrder, runText)
			}
		}

		BeforeEach(func() {
			randomizeAllSpecs = false
			randomSeed = 11
			parallelNode = 1
			parallelTotal = 1
			focusString = ""

			runOrder = make([]string, 0)
			specSuite.SetBeforeSuiteNode(f("BeforeSuite"), codelocation.New(0), 0)
			specSuite.PushBeforeEachNode(f("top BE"), codelocation.New(0), 0)
			specSuite.PushJustBeforeEachNode(f("top JBE"), codelocation.New(0), 0)
			specSuite.PushAfterEachNode(f("top AE"), codelocation.New(0), 0)

			specSuite.PushContainerNode("container", func() {
				specSuite.PushBeforeEachNode(f("BE"), codelocation.New(0), 0)
				specSuite.PushJustBeforeEachNode(f("JBE"), codelocation.New(0), 0)
				specSuite.PushAfterEachNode(f("AE"), codelocation.New(0), 0)
				specSuite.PushItNode("it", f("IT"), types.FlagTypeNone, codelocation.New(0), 0)

				specSuite.PushContainerNode("inner container", func() {
					specSuite.PushItNode("inner it", f("inner IT"), types.FlagTypeNone, codelocation.New(0), 0)
				}, types.FlagTypeNone, codelocation.New(0))
			}, types.FlagTypeNone, codelocation.New(0))
Beispiel #10
0
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/failer"
	. "github.com/gocircuit/escher/github.com/onsi/gomega"

	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/codelocation"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
)

var _ = Describe("Failer", func() {
	var (
		failer        *Failer
		codeLocationA types.CodeLocation
		codeLocationB types.CodeLocation
	)

	BeforeEach(func() {
		codeLocationA = codelocation.New(0)
		codeLocationB = codelocation.New(0)
		failer = New()
	})

	Context("with no failures", func() {
		It("should return success when drained", func() {
			failure, state := failer.Drain(types.SpecComponentTypeIt, 3, codeLocationB)
			Ω(failure).Should(BeZero())
			Ω(state).Should(Equal(types.SpecStatePassed))
		})
	})

	Describe("Fail", func() {
		It("should handle failures", func() {
			failer.Fail("something failed", codeLocationA)
Beispiel #11
0
	newContainer := func(text string, flag types.FlagType, setupNodes ...leafnodes.BasicNode) *containernode.ContainerNode {
		c := containernode.New(text, flag, codeLocation)
		for _, node := range setupNodes {
			c.PushSetupNode(node)
		}
		return c
	}

	containers := func(containers ...*containernode.ContainerNode) []*containernode.ContainerNode {
		return containers
	}

	BeforeEach(func() {
		failer = Failer.New()
		codeLocation = codelocation.New(0)
		nodesThatRan = []string{}
	})

	Describe("marking specs focused and pending", func() {
		It("should satisfy various caes", func() {
			cases := []struct {
				ContainerFlags []types.FlagType
				SubjectFlag    types.FlagType
				Pending        bool
				Focused        bool
			}{
				{[]types.FlagType{}, noneFlag, false, false},
				{[]types.FlagType{}, focusedFlag, false, true},
				{[]types.FlagType{}, pendingFlag, true, false},
				{[]types.FlagType{noneFlag}, noneFlag, false, false},
Beispiel #12
0
package leafnodes_test

import (
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
	. "github.com/gocircuit/escher/github.com/onsi/gomega"

	. "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/leafnodes"

	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/codelocation"
)

var _ = Describe("Setup Nodes", func() {
	Describe("BeforeEachNodes", func() {
		It("should report the correct type and code location", func() {
			codeLocation := codelocation.New(0)
			beforeEach := NewBeforeEachNode(func() {}, codeLocation, 0, nil, 3)
			Ω(beforeEach.Type()).Should(Equal(types.SpecComponentTypeBeforeEach))
			Ω(beforeEach.CodeLocation()).Should(Equal(codeLocation))
		})
	})

	Describe("AfterEachNodes", func() {
		It("should report the correct type and code location", func() {
			codeLocation := codelocation.New(0)
			afterEach := NewAfterEachNode(func() {}, codeLocation, 0, nil, 3)
			Ω(afterEach.Type()).Should(Equal(types.SpecComponentTypeAfterEach))
			Ω(afterEach.CodeLocation()).Should(Equal(codeLocation))
		})
	})
Beispiel #13
0
func SynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType, componentIndex int) {
	var (
		outcome types.SpecState
		failure types.SpecFailure

		failer *Failer.Failer

		componentCodeLocation types.CodeLocation
		innerCodeLocation     types.CodeLocation

		didRun bool
	)

	BeforeEach(func() {
		failer = Failer.New()
		componentCodeLocation = codelocation.New(0)
		innerCodeLocation = codelocation.New(0)

		didRun = false
	})

	Describe("synchronous functions", func() {
		Context("when the function passes", func() {
			BeforeEach(func() {
				outcome, failure = build(func() {
					didRun = true
				}, 0, failer, componentCodeLocation).Run()
			})

			It("should have a succesful outcome", func() {
				Ω(didRun).Should(BeTrue())

				Ω(outcome).Should(Equal(types.SpecStatePassed))
				Ω(failure).Should(BeZero())
			})
		})

		Context("when a failure occurs", func() {
			BeforeEach(func() {
				outcome, failure = build(func() {
					didRun = true
					failer.Fail("bam", innerCodeLocation)
					panic("should not matter")
				}, 0, failer, componentCodeLocation).Run()
			})

			It("should return the failure", func() {
				Ω(didRun).Should(BeTrue())

				Ω(outcome).Should(Equal(types.SpecStateFailed))
				Ω(failure).Should(Equal(types.SpecFailure{
					Message:               "bam",
					Location:              innerCodeLocation,
					ForwardedPanic:        nil,
					ComponentIndex:        componentIndex,
					ComponentType:         componentType,
					ComponentCodeLocation: componentCodeLocation,
				}))
			})
		})

		Context("when a panic occurs", func() {
			BeforeEach(func() {
				outcome, failure = build(func() {
					didRun = true
					innerCodeLocation = codelocation.New(0)
					panic("ack!")
				}, 0, failer, componentCodeLocation).Run()
			})

			It("should return the panic", func() {
				Ω(didRun).Should(BeTrue())

				Ω(outcome).Should(Equal(types.SpecStatePanicked))
				innerCodeLocation.LineNumber++
				Ω(failure).Should(Equal(types.SpecFailure{
					Message:               "Test Panicked",
					Location:              innerCodeLocation,
					ForwardedPanic:        "ack!",
					ComponentIndex:        componentIndex,
					ComponentType:         componentType,
					ComponentCodeLocation: componentCodeLocation,
				}))
			})
		})
	})
}
Beispiel #14
0
func AsynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType, componentIndex int) {
	var (
		outcome types.SpecState
		failure types.SpecFailure

		failer *Failer.Failer

		componentCodeLocation types.CodeLocation
		innerCodeLocation     types.CodeLocation

		didRun bool
	)

	BeforeEach(func() {
		failer = Failer.New()
		componentCodeLocation = codelocation.New(0)
		innerCodeLocation = codelocation.New(0)

		didRun = false
	})

	Describe("asynchronous functions", func() {
		var timeoutDuration time.Duration

		BeforeEach(func() {
			timeoutDuration = time.Duration(1 * float64(time.Second))
		})

		Context("when running", func() {
			It("should run the function as a goroutine, and block until it's done", func() {
				initialNumberOfGoRoutines := runtime.NumGoroutine()
				numberOfGoRoutines := 0

				build(func(done Done) {
					didRun = true
					numberOfGoRoutines = runtime.NumGoroutine()
					close(done)
				}, timeoutDuration, failer, componentCodeLocation).Run()

				Ω(didRun).Should(BeTrue())
				Ω(numberOfGoRoutines).Should(BeNumerically(">=", initialNumberOfGoRoutines+1))
			})
		})

		Context("when the function passes", func() {
			BeforeEach(func() {
				outcome, failure = build(func(done Done) {
					didRun = true
					close(done)
				}, timeoutDuration, failer, componentCodeLocation).Run()
			})

			It("should have a succesful outcome", func() {
				Ω(didRun).Should(BeTrue())
				Ω(outcome).Should(Equal(types.SpecStatePassed))
				Ω(failure).Should(BeZero())
			})
		})

		Context("when the function fails", func() {
			BeforeEach(func() {
				outcome, failure = build(func(done Done) {
					didRun = true
					failer.Fail("bam", innerCodeLocation)
					time.Sleep(20 * time.Millisecond)
					panic("doesn't matter")
					close(done)
				}, 10*time.Millisecond, failer, componentCodeLocation).Run()
			})

			It("should return the failure", func() {
				Ω(didRun).Should(BeTrue())

				Ω(outcome).Should(Equal(types.SpecStateFailed))
				Ω(failure).Should(Equal(types.SpecFailure{
					Message:               "bam",
					Location:              innerCodeLocation,
					ForwardedPanic:        nil,
					ComponentIndex:        componentIndex,
					ComponentType:         componentType,
					ComponentCodeLocation: componentCodeLocation,
				}))
			})
		})

		Context("when the function times out", func() {
			var guard chan struct{}

			BeforeEach(func() {
				guard = make(chan struct{})
				outcome, failure = build(func(done Done) {
					didRun = true
					time.Sleep(20 * time.Millisecond)
					close(guard)
					panic("doesn't matter")
					close(done)
				}, 10*time.Millisecond, failer, componentCodeLocation).Run()
			})

			It("should return the timeout", func() {
				<-guard
				Ω(didRun).Should(BeTrue())

				Ω(outcome).Should(Equal(types.SpecStateTimedOut))
				Ω(failure).Should(Equal(types.SpecFailure{
					Message:               "Timed out",
					Location:              componentCodeLocation,
					ForwardedPanic:        nil,
					ComponentIndex:        componentIndex,
					ComponentType:         componentType,
					ComponentCodeLocation: componentCodeLocation,
				}))
			})
		})

		Context("when the function panics", func() {
			BeforeEach(func() {
				outcome, failure = build(func(done Done) {
					didRun = true
					innerCodeLocation = codelocation.New(0)
					panic("ack!")
				}, 100*time.Millisecond, failer, componentCodeLocation).Run()
			})

			It("should return the panic", func() {
				Ω(didRun).Should(BeTrue())

				Ω(outcome).Should(Equal(types.SpecStatePanicked))
				innerCodeLocation.LineNumber++
				Ω(failure).Should(Equal(types.SpecFailure{
					Message:               "Test Panicked",
					Location:              innerCodeLocation,
					ForwardedPanic:        "ack!",
					ComponentIndex:        componentIndex,
					ComponentType:         componentType,
					ComponentCodeLocation: componentCodeLocation,
				}))
			})
		})
	})
}
Beispiel #15
0
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/codelocation"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
	. "github.com/gocircuit/escher/github.com/onsi/gomega"
	"runtime"
)

var _ = Describe("CodeLocation", func() {
	var (
		codeLocation       types.CodeLocation
		expectedFileName   string
		expectedLineNumber int
	)

	caller0 := func() {
		codeLocation = codelocation.New(1)
	}

	caller1 := func() {
		_, expectedFileName, expectedLineNumber, _ = runtime.Caller(0)
		expectedLineNumber += 2
		caller0()
	}

	BeforeEach(func() {
		caller1()
	})

	It("should use the passed in skip parameter to pick out the correct file & line number", func() {
		Ω(codeLocation.FileName).Should(Equal(expectedFileName))
		Ω(codeLocation.LineNumber).Should(Equal(expectedLineNumber))
Beispiel #16
0
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo"
	. "github.com/gocircuit/escher/github.com/onsi/gomega"

	"github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/codelocation"
	. "github.com/gocircuit/escher/github.com/onsi/ginkgo/internal/containernode"
	"github.com/gocircuit/escher/github.com/onsi/ginkgo/types"
)

var _ = Describe("Container Node", func() {
	var (
		codeLocation types.CodeLocation
		container    *ContainerNode
	)

	BeforeEach(func() {
		codeLocation = codelocation.New(0)
		container = New("description text", types.FlagTypeFocused, codeLocation)
	})

	Describe("creating a container node", func() {
		It("can answer questions about itself", func() {
			Ω(container.Text()).Should(Equal("description text"))
			Ω(container.Flag()).Should(Equal(types.FlagTypeFocused))
			Ω(container.CodeLocation()).Should(Equal(codeLocation))
		})
	})

	Describe("pushing setup nodes", func() {
		It("can append setup nodes of various types and fetch them by type", func() {
			befA := leafnodes.NewBeforeEachNode(func() {}, codelocation.New(0), 0, nil, 0)
			befB := leafnodes.NewBeforeEachNode(func() {}, codelocation.New(0), 0, nil, 0)