@@ -10,82 +10,141 @@ import (
1010 "github.com/sqlc-dev/sqlc/internal/cmd"
1111)
1212
13- func TestEmitIteratorsCodegenGlobal (t * testing.T ) {
14- t .Parallel ()
15- ctx := context .Background ()
13+ type emitIterCase struct {
14+ name string
15+ root string
16+ mustHave []string
17+ mustNot []string
18+ exactIter int // -1 = don't check count
19+ }
1620
17- root := filepath .Join ("testdata" , "emit_iterators" , "stdlib" )
18- abs , err := filepath .Abs (root )
19- if err != nil {
20- t .Fatal (err )
21+ func TestEmitIteratorsCodegenMatrix (t * testing.T ) {
22+ cases := []emitIterCase {
23+ {
24+ name : "global stdlib" ,
25+ root : filepath .Join ("testdata" , "emit_iterators" , "stdlib" ),
26+ mustHave : []string {
27+ "func (q *Queries) ListAuthors" ,
28+ "func (q *Queries) IterAuthors" ,
29+ "iter.Seq2[Author, error]" ,
30+ "defer rows.Close()" ,
31+ },
32+ mustNot : []string {"sqlc:iterator-stream" },
33+ exactIter : 1 ,
34+ },
35+ {
36+ name : "explicit_only stream query" ,
37+ root : filepath .Join ("testdata" , "emit_iterators_explicit" , "stdlib" ),
38+ mustHave : []string {
39+ "func (q *Queries) StreamAuthors" ,
40+ "func (q *Queries) IterAuthors" ,
41+ "q.db.QueryContext(ctx, streamAuthors)" ,
42+ },
43+ mustNot : []string {"sqlc:iterator-stream" },
44+ exactIter : 1 ,
45+ },
46+ {
47+ name : "explicit_only many:stream annotation" ,
48+ root : filepath .Join ("testdata" , "emit_iterators_many_stream" , "stdlib" ),
49+ mustHave : []string {
50+ "func (q *Queries) IterAuthors" ,
51+ "func (q *Queries) ListAllAuthors" ,
52+ },
53+ mustNot : []string {
54+ "func (q *Queries) IterAllAuthors" ,
55+ "sqlc:iterator-stream" ,
56+ },
57+ exactIter : 1 ,
58+ },
59+ {
60+ name : "parameterized many" ,
61+ root : filepath .Join ("testdata" , "emit_iterators_params" , "stdlib" ),
62+ mustHave : []string {
63+ "func (q *Queries) ListAuthorsByMinID(ctx context.Context, id int64)" ,
64+ "func (q *Queries) IterAuthorsByMinID(ctx context.Context, id int64) iter.Seq2[Author, error]" ,
65+ },
66+ exactIter : 1 ,
67+ },
68+ {
69+ name : "emit_iterators disabled" ,
70+ root : filepath .Join ("testdata" , "emit_iterators_off" , "stdlib" ),
71+ mustHave : []string {
72+ "func (q *Queries) ListAuthors" ,
73+ },
74+ mustNot : []string {
75+ "iter.Seq2" ,
76+ "func (q *Queries) Iter" ,
77+ },
78+ exactIter : 0 ,
79+ },
80+ {
81+ name : "pgx v5" ,
82+ root : filepath .Join ("testdata" , "emit_iterators" , "pgx" , "v5" ),
83+ mustHave : []string {
84+ "func (q *Queries) IterAuthors(ctx context.Context) iter.Seq2[Author, error]" ,
85+ "rows, err := q.db.Query(ctx, listAuthors" ,
86+ "defer rows.Close()" ,
87+ },
88+ exactIter : 1 ,
89+ },
2190 }
2291
23- var stderr strings.Builder
24- _ , err = cmd .Generate (ctx , abs , "" , & cmd.Options {Stderr : & stderr })
25- if err != nil {
26- t .Fatalf ("generate failed: %v\n %s" , err , stderr .String ())
27- }
92+ for _ , tc := range cases {
93+ t .Run (tc .name , func (t * testing.T ) {
94+ ctx := context .Background ()
95+ abs , err := filepath .Abs (tc .root )
96+ if err != nil {
97+ t .Fatal (err )
98+ }
2899
29- queryFile := filepath .Join (abs , "go" , "query.sql.go" )
30- body , err := os .ReadFile (queryFile )
31- if err != nil {
32- t .Fatal (err )
33- }
34- src := string (body )
35- for _ , want := range []string {
36- "func (q *Queries) ListAuthors" ,
37- "func (q *Queries) IterAuthors" ,
38- "iter.Seq2[Author, error]" ,
39- "defer rows.Close()" ,
40- } {
41- if ! strings .Contains (src , want ) {
42- t .Fatalf ("missing %q in generated code:\n %s" , want , src )
43- }
44- }
45- if strings .Contains (src , "sqlc:iterator-stream" ) {
46- t .Fatal ("internal stream marker leaked into generated code" )
100+ var stderr strings.Builder
101+ if _ , err := cmd .Generate (ctx , abs , "" , & cmd.Options {Stderr : & stderr }); err != nil {
102+ t .Fatalf ("generate failed: %v\n %s" , err , stderr .String ())
103+ }
104+
105+ queryFile := filepath .Join (abs , "go" , "query.sql.go" )
106+ body , err := os .ReadFile (queryFile )
107+ if err != nil {
108+ t .Fatal (err )
109+ }
110+ src := string (body )
111+
112+ for _ , want := range tc .mustHave {
113+ if ! strings .Contains (src , want ) {
114+ t .Fatalf ("missing %q in:\n %s" , want , src )
115+ }
116+ }
117+ for _ , bad := range tc .mustNot {
118+ if strings .Contains (src , bad ) {
119+ t .Fatalf ("unexpected %q in:\n %s" , bad , src )
120+ }
121+ }
122+ if tc .exactIter >= 0 {
123+ count := strings .Count (src , "func (q *Queries) Iter" )
124+ if count != tc .exactIter {
125+ t .Fatalf ("Iter method count = %d, want %d\n %s" , count , tc .exactIter , src )
126+ }
127+ }
128+ })
47129 }
48130}
49131
50- func TestEmitIteratorsCodegenExplicitOnly (t * testing.T ) {
51- t .Parallel ()
52- ctx := context .Background ()
53-
54- root := filepath .Join ("testdata" , "emit_iterators_explicit" , "stdlib" )
132+ func TestEmitIteratorsExplicitOnlySkipsPlainMany (t * testing.T ) {
133+ root := filepath .Join ("testdata" , "emit_iterators_many_stream" , "stdlib" )
55134 abs , err := filepath .Abs (root )
56135 if err != nil {
57136 t .Fatal (err )
58137 }
59-
60138 var stderr strings.Builder
61- _ , err = cmd .Generate (ctx , abs , "" , & cmd.Options {Stderr : & stderr })
62- if err != nil {
63- t .Fatalf ("generate failed: %v\n %s" , err , stderr .String ())
139+ if _ , err := cmd .Generate (context .Background (), abs , "" , & cmd.Options {Stderr : & stderr }); err != nil {
140+ t .Fatal (err )
64141 }
65-
66- queryFile := filepath .Join (abs , "go" , "query.sql.go" )
67- body , err := os .ReadFile (queryFile )
142+ body , err := os .ReadFile (filepath .Join (abs , "go" , "query.sql.go" ))
68143 if err != nil {
69144 t .Fatal (err )
70145 }
71146 src := string (body )
72- if strings .Contains (src , "sqlc:iterator-stream" ) {
73- t .Fatal ("internal stream marker leaked into generated code" )
74- }
75- if strings .Count (src , "func (q *Queries) IterAuthors" ) != 1 {
76- t .Fatalf ("expected exactly one IterAuthors, got:\n %s" , src )
77- }
78- for _ , want := range []string {
79- "func (q *Queries) StreamAuthors" ,
80- "func (q *Queries) IterAuthors" ,
81- "q.db.QueryContext(ctx, streamAuthors)" ,
82- } {
83- if ! strings .Contains (src , want ) {
84- t .Fatalf ("missing %q in generated code:\n %s" , want , src )
85- }
86- }
87- listAuthorsBlock := src [strings .Index (src , "func (q *Queries) ListAuthors" ):strings .Index (src , "const streamAuthors" )]
88- if strings .Contains (listAuthorsBlock , "IterAuthors" ) {
89- t .Fatal ("ListAuthors block must not contain iterator method" )
147+ if strings .Contains (src , "IterAllAuthors" ) {
148+ t .Fatal ("plain :many must not get iterator in explicit_only mode" )
90149 }
91150}
0 commit comments