How to use FromASTFile method of outline Package

Best Ginkgo code snippet using outline.FromASTFile

Run Ginkgo automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

outline.go

Source: outline.go Github

copy
1package outline
2
3import (
4	"encoding/json"
5	"fmt"
6	"go/ast"
7	"go/token"
8	"strings"
9
10	"golang.org/x/tools/go/ast/inspector"
11)
12
13const (
14	// ginkgoImportPath is the well-known ginkgo import path
15	ginkgoImportPath = "github.com/onsi/ginkgo"
16
17	// tableImportPath is the well-known table extension import path
18	tableImportPath = "github.com/onsi/ginkgo/extensions/table"
19)
20
21// FromASTFile returns an outline for a Ginkgo test source file
22func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) {
23	ginkgoPackageName := packageNameForImport(src, ginkgoImportPath)
24	tablePackageName := packageNameForImport(src, tableImportPath)
25	if ginkgoPackageName == nil && tablePackageName == nil {
26		return nil, fmt.Errorf("file does not import %q or %q", ginkgoImportPath, tableImportPath)
27	}
28
29	root := ginkgoNode{}
30	stack := []*ginkgoNode{&root}
31	ispr := inspector.New([]*ast.File{src})
32	ispr.Nodes([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool) bool {
33		if push {
34			// Pre-order traversal
35			ce, ok := node.(*ast.CallExpr)
36			if !ok {
37				// Because `Nodes` calls this function only when the node is an
38				// ast.CallExpr, this should never happen
39				panic(fmt.Errorf("node starting at %d, ending at %d is not an *ast.CallExpr", node.Pos(), node.End()))
40			}
41			gn, ok := ginkgoNodeFromCallExpr(fset, ce, ginkgoPackageName, tablePackageName)
42			if !ok {
43				// Node is not a Ginkgo spec or container, continue
44				return true
45			}
46			parent := stack[len(stack)-1]
47			parent.Nodes = append(parent.Nodes, gn)
48			stack = append(stack, gn)
49			return true
50		}
51		// Post-order traversal
52		start, end := absoluteOffsetsForNode(fset, node)
53		lastVisitedGinkgoNode := stack[len(stack)-1]
54		if start != lastVisitedGinkgoNode.Start || end != lastVisitedGinkgoNode.End {
55			// Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue
56			return true
57		}
58		stack = stack[0 : len(stack)-1]
59		return true
60	})
61	if len(root.Nodes) == 0 {
62		return &outline{[]*ginkgoNode{}}, nil
63	}
64
65	// Derive the final focused property for all nodes. This must be done
66	// _before_ propagating the inherited focused property.
67	root.BackpropagateUnfocus()
68	// Now, propagate inherited properties, including focused and pending.
69	root.PropagateInheritedProperties()
70
71	return &outline{root.Nodes}, nil
72}
73
74type outline struct {
75	Nodes []*ginkgoNode `json:"nodes"`
76}
77
78func (o *outline) MarshalJSON() ([]byte, error) {
79	return json.Marshal(o.Nodes)
80}
81
82// String returns a CSV-formatted outline. Spec or container are output in
83// depth-first order.
84func (o *outline) String() string {
85	return o.StringIndent(0)
86}
87
88// StringIndent returns a CSV-formated outline, but every line is indented by
89// one 'width' of spaces for every level of nesting.
90func (o *outline) StringIndent(width int) string {
91	var b strings.Builder
92	b.WriteString("Name,Text,Start,End,Spec,Focused,Pending\n")
93
94	currentIndent := 0
95	pre := func(n *ginkgoNode) {
96		b.WriteString(fmt.Sprintf("%*s", currentIndent, ""))
97		b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending))
98		currentIndent += width
99	}
100	post := func(n *ginkgoNode) {
101		currentIndent -= width
102	}
103	for _, n := range o.Nodes {
104		n.Walk(pre, post)
105	}
106	return b.String()
107}
108
Full Screen

outline_test.go

Source: outline_test.go Github

copy
1package outline
2
3import (
4	"encoding/json"
5	"fmt"
6	"go/parser"
7	"go/token"
8	"io/ioutil"
9	"log"
10	"path/filepath"
11	"strconv"
12	"strings"
13
14	. "github.com/onsi/ginkgo"
15	. "github.com/onsi/ginkgo/extensions/table"
16	. "github.com/onsi/gomega"
17)
18
19var _ = DescribeTable("Validate outline from file with",
20	func(srcFilename, jsonOutlineFilename, csvOutlineFilename string) {
21		fset := token.NewFileSet()
22		astFile, err := parser.ParseFile(fset, filepath.Join("_testdata", srcFilename), nil, 0)
23		Expect(err).To(BeNil(), "error parsing source: %s", err)
24
25		if err != nil {
26			log.Fatalf("error parsing source: %s", err)
27		}
28
29		o, err := FromASTFile(fset, astFile)
30		Expect(err).To(BeNil(), "error creating outline: %s", err)
31
32		gotJSON, err := json.MarshalIndent(o, "", "  ")
33		Expect(err).To(BeNil(), "error marshalling outline to json: %s", err)
34
35		wantJSON, err := ioutil.ReadFile(filepath.Join("_testdata", jsonOutlineFilename))
36		Expect(err).To(BeNil(), "error reading JSON outline fixture: %s", err)
37
38		Expect(gotJSON).To(MatchJSON(wantJSON))
39
40		gotCSV := o.String()
41
42		wantCSV, err := ioutil.ReadFile(filepath.Join("_testdata", csvOutlineFilename))
43		Expect(err).To(BeNil(), "error reading CSV outline fixture: %s", err)
44
45		Expect(gotCSV).To(Equal(string(wantCSV)))
46	},
47	// To add a test:
48	// 1. Create the input, e.g., `myspecialcase_test.go`
49	// 2. Create the sample CSV and JSON results: Run `bash ./_testdata/create_result.sh ./_testdata/myspecialcase_test.go`
50	// 3. Add an Entry below, by copying an existing one, and substituting `myspecialcase` where needed.
51	// To re-create the sample results for a test:
52	// 1. Run `bash ./_testdata/create_result.sh ./testdata/myspecialcase_test.go`
53	// To re-create the sample results for all tests:
54	// 1. Run `for name in ./_testdata/*_test.go; do bash ./_testdata/create_result.sh $name; done`
55	Entry("normal import of ginkgo package (no dot, no alias), normal container and specs", "nodot_test.go", "nodot_test.go.json", "nodot_test.go.csv"),
56	Entry("aliased import of ginkgo package, normal container and specs", "alias_test.go", "alias_test.go.json", "alias_test.go.csv"),
57	Entry("normal containers and specs", "normal_test.go", "normal_test.go.json", "normal_test.go.csv"),
58	Entry("focused containers and specs", "focused_test.go", "focused_test.go.json", "focused_test.go.csv"),
59	Entry("pending containers and specs", "pending_test.go", "pending_test.go.json", "pending_test.go.csv"),
60	Entry("nested focused containers and specs", "nestedfocused_test.go", "nestedfocused_test.go.json", "nestedfocused_test.go.csv"),
61	Entry("mixed focused containers and specs", "mixed_test.go", "mixed_test.go.json", "mixed_test.go.csv"),
62	Entry("specs used to verify position", "position_test.go", "position_test.go.json", "position_test.go.csv"),
63	Entry("suite setup", "suite_test.go", "suite_test.go.json", "suite_test.go.csv"),
64)
65
66var _ = Describe("Validate position", func() {
67
68	It("should report the correct start and end byte offsets of the ginkgo container or spec", func() {
69		fset := token.NewFileSet()
70		astFile, err := parser.ParseFile(fset, filepath.Join("_testdata", "position_test.go"), nil, 0)
71		Expect(err).To(BeNil(), "error parsing source: %s", err)
72
73		if err != nil {
74			log.Fatalf("error parsing source: %s", err)
75		}
76
77		o, err := FromASTFile(fset, astFile)
78		Expect(err).To(BeNil(), "error creating outline: %s", err)
79
80		for _, n := range o.Nodes {
81			n.PreOrder(func(n *ginkgoNode) {
82				wantPositions := strings.Split(n.Text, ",")
83				Expect(len(wantPositions)).To(Equal(2), "test fixture node text should be \"start position,end position")
84				wantStart, err := strconv.Atoi(wantPositions[0])
85				Expect(err).To(BeNil(), "could not parse start offset")
86				wantEnd, err := strconv.Atoi(wantPositions[1])
87				Expect(err).To(BeNil(), "could not parse end offset")
88
89				Expect(int(n.Start)).To(Equal(wantStart), fmt.Sprintf("test fixture node text says the node should start at %d, but it starts at %d", wantStart, n.Start))
90				Expect(int(n.End)).To(Equal(wantEnd), fmt.Sprintf("test fixture node text says the node should end at %d, but it ends at %d", wantEnd, n.End))
91			})
92		}
93
94	})
95})
96
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Trigger FromASTFile code on LambdaTest Cloud Grid

Execute automation tests with FromASTFile on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)