1
1
//! Tests for `candidate_reviewers_from_names`
2
2
3
3
use super :: super :: * ;
4
+ use crate :: tests:: github:: { issue, user} ;
4
5
5
- /// Basic test function for testing `candidate_reviewers_from_names`.
6
- fn test_from_names (
7
- teams : Option < toml:: Table > ,
8
- config : toml:: Table ,
9
- issue : serde_json:: Value ,
10
- names : & [ & str ] ,
11
- expected : Result < & [ & str ] , FindReviewerError > ,
12
- ) {
13
- let ( teams, config, issue) = convert_simplified ( teams, config, issue) ;
14
- let names: Vec < _ > = names. iter ( ) . map ( |n| n. to_string ( ) ) . collect ( ) ;
15
- match (
16
- candidate_reviewers_from_names ( & teams, & config, & issue, & names) ,
17
- expected,
18
- ) {
19
- ( Ok ( candidates) , Ok ( expected) ) => {
20
- let mut candidates: Vec < _ > = candidates. into_iter ( ) . collect ( ) ;
21
- candidates. sort ( ) ;
22
- let expected: Vec < _ > = expected. iter ( ) . map ( |x| * x) . collect ( ) ;
23
- assert_eq ! ( candidates, expected) ;
6
+ #[ must_use]
7
+ struct TestCtx {
8
+ teams : Teams ,
9
+ config : AssignConfig ,
10
+ issue : Issue ,
11
+ }
12
+
13
+ impl TestCtx {
14
+ fn new ( config : toml:: Table , issue : Issue ) -> Self {
15
+ Self {
16
+ teams : Teams {
17
+ teams : Default :: default ( ) ,
18
+ } ,
19
+ config : config. try_into ( ) . unwrap ( ) ,
20
+ issue,
24
21
}
25
- ( Err ( actual) , Err ( expected) ) => {
26
- assert_eq ! ( actual, expected)
22
+ }
23
+
24
+ fn teams ( mut self , table : & toml:: Table ) -> Self {
25
+ let teams: serde_json:: Value = table. clone ( ) . try_into ( ) . unwrap ( ) ;
26
+ let mut teams_config = serde_json:: json!( { } ) ;
27
+ for ( team_name, members) in teams. as_object ( ) . unwrap ( ) {
28
+ let members: Vec < _ > = members. as_array ( ) . unwrap ( ) . iter ( ) . map ( |member| {
29
+ serde_json:: json!( { "name" : member, "github" : member, "github_id" : 100 , "is_lead" : false } )
30
+ } ) . collect ( ) ;
31
+ teams_config[ team_name] = serde_json:: json!( {
32
+ "name" : team_name,
33
+ "kind" : "team" ,
34
+ "members" : serde_json:: Value :: Array ( members) ,
35
+ "alumni" : [ ] ,
36
+ "discord" : [ ] ,
37
+ "roles" : [ ] ,
38
+ } ) ;
27
39
}
28
- ( Ok ( candidates ) , Err ( _ ) ) => panic ! ( "expected Err, got Ok: {candidates:?}" ) ,
29
- ( Err ( e ) , Ok ( _ ) ) => panic ! ( "expected Ok, got Err: {e}" ) ,
40
+ self . teams = serde_json :: value :: from_value ( teams_config ) . unwrap ( ) ;
41
+ self
30
42
}
31
- }
32
43
33
- /// Convert the simplified input in preparation for `candidate_reviewers_from_names`.
34
- fn convert_simplified (
35
- teams : Option < toml:: Table > ,
36
- config : toml:: Table ,
37
- issue : serde_json:: Value ,
38
- ) -> ( Teams , AssignConfig , Issue ) {
39
- // Convert the simplified team config to a real team config.
40
- // This uses serde_json since it is easier to manipulate than toml.
41
- let teams: serde_json:: Value = match teams {
42
- Some ( teams) => teams. try_into ( ) . unwrap ( ) ,
43
- None => serde_json:: json!( { } ) ,
44
- } ;
45
- let mut teams_config = serde_json:: json!( { } ) ;
46
- for ( team_name, members) in teams. as_object ( ) . unwrap ( ) {
47
- let members: Vec < _ > = members. as_array ( ) . unwrap ( ) . iter ( ) . map ( |member| {
48
- serde_json:: json!( { "name" : member, "github" : member, "github_id" : 1 , "is_lead" : false } )
49
- } ) . collect ( ) ;
50
- teams_config[ team_name] = serde_json:: json!( {
51
- "name" : team_name,
52
- "kind" : "team" ,
53
- "members" : serde_json:: Value :: Array ( members) ,
54
- "alumni" : [ ] ,
55
- "discord" : [ ] ,
56
- "roles" : [ ] ,
57
- } ) ;
44
+ fn run ( self , names : & [ & str ] , expected : Result < & [ & str ] , FindReviewerError > ) {
45
+ let names: Vec < _ > = names. iter ( ) . map ( |n| n. to_string ( ) ) . collect ( ) ;
46
+ match (
47
+ candidate_reviewers_from_names ( & self . teams , & self . config , & self . issue , & names) ,
48
+ expected,
49
+ ) {
50
+ ( Ok ( candidates) , Ok ( expected) ) => {
51
+ let mut candidates: Vec < _ > = candidates. into_iter ( ) . collect ( ) ;
52
+ candidates. sort ( ) ;
53
+ let expected: Vec < _ > = expected. iter ( ) . map ( |x| * x) . collect ( ) ;
54
+ assert_eq ! ( candidates, expected) ;
55
+ }
56
+ ( Err ( actual) , Err ( expected) ) => {
57
+ assert_eq ! ( actual, expected)
58
+ }
59
+ ( Ok ( candidates) , Err ( _) ) => panic ! ( "expected Err, got Ok: {candidates:?}" ) ,
60
+ ( Err ( e) , Ok ( _) ) => panic ! ( "expected Ok, got Err: {e}" ) ,
61
+ }
58
62
}
59
- let teams = serde_json:: value:: from_value ( teams_config) . unwrap ( ) ;
60
- let config = config. try_into ( ) . unwrap ( ) ;
61
- let issue = serde_json:: value:: from_value ( issue) . unwrap ( ) ;
62
- ( teams, config, issue)
63
63
}
64
64
65
- fn generic_issue ( author : & str , repo : & str ) -> serde_json:: Value {
66
- serde_json:: json!( {
67
- "number" : 1234 ,
68
- "created_at" : "2022-06-26T21:31:31Z" ,
69
- "updated_at" : "2022-06-26T21:31:31Z" ,
70
- "title" : "Example PR" ,
71
- "body" : "PR body" ,
72
- "html_url" : "https://github.com/rust-lang/rust/pull/1234" ,
73
- "user" : {
74
- "login" : author,
75
- "id" : 583231 ,
76
- } ,
77
- "labels" : [ ] ,
78
- "assignees" : [ ] ,
79
- "comments_url" : format!( "https://api.github.com/repos/{repo}/pull/1234/comments" ) ,
80
- "state" : "open" ,
81
- } )
65
+ /// Basic test function for testing `candidate_reviewers_from_names`.
66
+ fn test_candidates ( config : toml:: Table , issue : Issue ) -> TestCtx {
67
+ TestCtx :: new ( config, issue)
82
68
}
83
69
84
70
#[ test]
@@ -89,11 +75,7 @@ fn circular_groups() {
89
75
compiler = [ "other" ]
90
76
other = [ "compiler" ]
91
77
) ;
92
- let issue = generic_issue ( "octocat" , "rust-lang/rust" ) ;
93
- test_from_names (
94
- None ,
95
- config,
96
- issue,
78
+ test_candidates ( config, issue ( ) . call ( ) ) . run (
97
79
& [ "compiler" ] ,
98
80
Err ( FindReviewerError :: NoReviewer {
99
81
initial : vec ! [ "compiler" . to_string( ) ] ,
@@ -110,8 +92,7 @@ fn nested_groups() {
110
92
b = [ "@nrc" ]
111
93
c = [ "a" , "b" ]
112
94
) ;
113
- let issue = generic_issue ( "octocat" , "rust-lang/rust" ) ;
114
- test_from_names ( None , config, issue, & [ "c" ] , Ok ( & [ "nrc" , "pnkfelix" ] ) ) ;
95
+ test_candidates ( config, issue ( ) . call ( ) ) . run ( & [ "c" ] , Ok ( & [ "nrc" , "pnkfelix" ] ) ) ;
115
96
}
116
97
117
98
#[ test]
@@ -121,11 +102,7 @@ fn candidate_filtered_author_only_candidate() {
121
102
[ adhoc_groups]
122
103
compiler = [ "nikomatsakis" ]
123
104
) ;
124
- let issue = generic_issue ( "nikomatsakis" , "rust-lang/rust" ) ;
125
- test_from_names (
126
- None ,
127
- config,
128
- issue,
105
+ test_candidates ( config, issue ( ) . author ( user ( "nikomatsakis" , 1 ) ) . call ( ) ) . run (
129
106
& [ "compiler" ] ,
130
107
Err ( FindReviewerError :: NoReviewer {
131
108
initial : vec ! [ "compiler" . to_string( ) ] ,
@@ -141,14 +118,8 @@ fn candidate_filtered_author() {
141
118
compiler = [ "user1" , "user2" , "user3" , "group2" ]
142
119
group2 = [ "user2" , "user4" ]
143
120
) ;
144
- let issue = generic_issue ( "user2" , "rust-lang/rust" ) ;
145
- test_from_names (
146
- None ,
147
- config,
148
- issue,
149
- & [ "compiler" ] ,
150
- Ok ( & [ "user1" , "user3" , "user4" ] ) ,
151
- ) ;
121
+ test_candidates ( config, issue ( ) . author ( user ( "user2" , 1 ) ) . call ( ) )
122
+ . run ( & [ "compiler" ] , Ok ( & [ "user1" , "user3" , "user4" ] ) ) ;
152
123
}
153
124
154
125
#[ test]
@@ -158,12 +129,11 @@ fn candidate_filtered_assignee() {
158
129
[ adhoc_groups]
159
130
compiler = [ "user1" , "user2" , "user3" , "user4" ]
160
131
) ;
161
- let mut issue = generic_issue ( "user2" , "rust-lang/rust" ) ;
162
- issue[ "assignees" ] = serde_json:: json!( [
163
- { "login" : "user1" , "id" : 1 } ,
164
- { "login" : "user3" , "id" : 3 } ,
165
- ] ) ;
166
- test_from_names ( None , config, issue, & [ "compiler" ] , Ok ( & [ "user4" ] ) ) ;
132
+ let issue = issue ( )
133
+ . author ( user ( "user2" , 2 ) )
134
+ . assignees ( vec ! [ user( "user1" , 1 ) , user( "user3" , 3 ) ] )
135
+ . call ( ) ;
136
+ test_candidates ( config, issue) . run ( & [ "compiler" ] , Ok ( & [ "user4" ] ) ) ;
167
137
}
168
138
169
139
#[ test]
@@ -177,11 +147,7 @@ fn groups_teams_users() {
177
147
[ adhoc_groups]
178
148
group1 = [ "user1" , "rust-lang/team2" ]
179
149
) ;
180
- let issue = generic_issue ( "octocat" , "rust-lang/rust" ) ;
181
- test_from_names (
182
- Some ( teams) ,
183
- config,
184
- issue,
150
+ test_candidates ( config, issue ( ) . call ( ) ) . teams ( & teams) . run (
185
151
& [ "team1" , "group1" , "user3" ] ,
186
152
Ok ( & [ "t-user1" , "t-user2" , "user1" , "user3" ] ) ,
187
153
) ;
@@ -195,21 +161,12 @@ fn group_team_user_precedence() {
195
161
[ adhoc_groups]
196
162
compiler = [ "user2" ]
197
163
) ;
198
- let issue = generic_issue ( "octocat" , "rust-lang/rust" ) ;
199
- test_from_names (
200
- Some ( teams. clone ( ) ) ,
201
- config. clone ( ) ,
202
- issue. clone ( ) ,
203
- & [ "compiler" ] ,
204
- Ok ( & [ "user2" ] ) ,
205
- ) ;
206
- test_from_names (
207
- Some ( teams. clone ( ) ) ,
208
- config. clone ( ) ,
209
- issue. clone ( ) ,
210
- & [ "rust-lang/compiler" ] ,
211
- Ok ( & [ "user2" ] ) ,
212
- ) ;
164
+ test_candidates ( config. clone ( ) , issue ( ) . call ( ) )
165
+ . teams ( & teams)
166
+ . run ( & [ "compiler" ] , Ok ( & [ "user2" ] ) ) ;
167
+ test_candidates ( config, issue ( ) . call ( ) )
168
+ . teams ( & teams)
169
+ . run ( & [ "rust-lang/compiler" ] , Ok ( & [ "user2" ] ) ) ;
213
170
}
214
171
215
172
#[ test]
@@ -221,22 +178,16 @@ fn what_do_slashes_mean() {
221
178
compiler = [ "user2" ]
222
179
"foo/bar" = [ "foo-user" ]
223
180
) ;
224
- let issue = generic_issue ( "octocat" , "rust-lang-nursery/rust" ) ;
181
+ let issue = || issue ( ) . org ( "rust-lang-nursery" ) . call ( ) ;
182
+
225
183
// Random slash names should work from groups.
226
- test_from_names (
227
- Some ( teams. clone ( ) ) ,
228
- config. clone ( ) ,
229
- issue. clone ( ) ,
230
- & [ "foo/bar" ] ,
231
- Ok ( & [ "foo-user" ] ) ,
232
- ) ;
233
- test_from_names (
234
- Some ( teams. clone ( ) ) ,
235
- config. clone ( ) ,
236
- issue. clone ( ) ,
237
- & [ "rust-lang-nursery/compiler" ] ,
238
- Ok ( & [ "user2" ] ) ,
239
- ) ;
184
+ test_candidates ( config. clone ( ) , issue ( ) )
185
+ . teams ( & teams)
186
+ . run ( & [ "foo/bar" ] , Ok ( & [ "foo-user" ] ) ) ;
187
+
188
+ test_candidates ( config, issue ( ) )
189
+ . teams ( & teams)
190
+ . run ( & [ "rust-lang-nursery/compiler" ] , Ok ( & [ "user2" ] ) ) ;
240
191
}
241
192
242
193
#[ test]
@@ -246,11 +197,7 @@ fn invalid_org_doesnt_match() {
246
197
[ adhoc_groups]
247
198
compiler = [ "user2" ]
248
199
) ;
249
- let issue = generic_issue ( "octocat" , "rust-lang/rust" ) ;
250
- test_from_names (
251
- Some ( teams) ,
252
- config,
253
- issue,
200
+ test_candidates ( config, issue ( ) . call ( ) ) . teams ( & teams) . run (
254
201
& [ "github/compiler" ] ,
255
202
Err ( FindReviewerError :: TeamNotFound (
256
203
"github/compiler" . to_string ( ) ,
@@ -262,25 +209,18 @@ fn invalid_org_doesnt_match() {
262
209
fn vacation ( ) {
263
210
let teams = toml:: toml!( bootstrap = [ "jyn514" , "Mark-Simulacrum" ] ) ;
264
211
let config = toml:: toml!( users_on_vacation = [ "jyn514" ] ) ;
265
- let issue = generic_issue ( "octocat" , "rust-lang/rust" ) ;
266
212
267
213
// Test that `r? user` returns a specific error about the user being on vacation.
268
- test_from_names (
269
- Some ( teams. clone ( ) ) ,
270
- config. clone ( ) ,
271
- issue. clone ( ) ,
272
- & [ "jyn514" ] ,
273
- Err ( FindReviewerError :: ReviewerOnVacation {
274
- username : "jyn514" . to_string ( ) ,
275
- } ) ,
276
- ) ;
277
-
278
- // Test that `r? bootstrap` doesn't assign from users on vacation.
279
- test_from_names (
280
- Some ( teams. clone ( ) ) ,
281
- config. clone ( ) ,
282
- issue,
283
- & [ "bootstrap" ] ,
284
- Ok ( & [ "Mark-Simulacrum" ] ) ,
285
- ) ;
214
+ test_candidates ( config. clone ( ) , issue ( ) . call ( ) )
215
+ . teams ( & teams)
216
+ . run (
217
+ & [ "jyn514" ] ,
218
+ Err ( FindReviewerError :: ReviewerOnVacation {
219
+ username : "jyn514" . to_string ( ) ,
220
+ } ) ,
221
+ ) ;
222
+
223
+ test_candidates ( config. clone ( ) , issue ( ) . call ( ) )
224
+ . teams ( & teams)
225
+ . run ( & [ "bootstrap" ] , Ok ( & [ "Mark-Simulacrum" ] ) ) ;
286
226
}
0 commit comments