Skip to content

Commit d14ee3d

Browse files
authored
test: Improve output tests (#41)
* chore: Add `[email protected]` to dev dependencies * test: Use `indoc` to improve string formatting - allows testing stdout explicitly - makes doc blocks more readable
1 parent 97e385a commit d14ee3d

File tree

6 files changed

+134
-125
lines changed

6 files changed

+134
-125
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ assert_cmd = "2.0.16"
2828
rusty-hook = "^0.11.2"
2929
predicates = "3.1.2"
3030
pretty_assertions = "1.4.1" # Shows a more readable diff when comparing objects
31+
indoc = "2.0.5"

src/common_test.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ pub mod tests {
66
path::PathBuf,
77
};
88

9+
use indoc::indoc;
10+
911
use tempfile::tempdir;
1012

1113
use crate::{ownership::Ownership, project::Project};
@@ -21,18 +23,18 @@ pub mod tests {
2123
}};
2224
}
2325

24-
const DEFAULT_CODE_OWNERSHIP_YML: &str = "
25-
---
26-
owned_globs:
27-
- \"{app,components,config,frontend,lib,packs,spec}/**/*.{rb,rake,js,jsx,ts,tsx,json,yml}\"
28-
unowned_globs:
29-
- config/code_ownership.yml
30-
javascript_package_paths:
31-
- javascript/packages/**
32-
vendored_gems_path: gems
33-
team_file_glob:
34-
- config/teams/**/*.yml
35-
";
26+
const DEFAULT_CODE_OWNERSHIP_YML: &str = indoc! {"
27+
---
28+
owned_globs:
29+
- \"{app,components,config,frontend,lib,packs,spec}/**/*.{rb,rake,js,jsx,ts,tsx,json,yml}\"
30+
unowned_globs:
31+
- config/code_ownership.yml
32+
javascript_package_paths:
33+
- javascript/packages/**
34+
vendored_gems_path: gems
35+
team_file_glob:
36+
- config/teams/**/*.yml
37+
"};
3638

3739
#[derive(Debug)]
3840
pub struct TestConfig {

src/ownership.rs

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ fn parse_for_team(team_name: String, codeowners_file: &str) -> Result<Vec<TeamOw
206206
mod tests {
207207
use super::*;
208208
use crate::common_test::tests::{build_ownership_with_all_mappers, vecs_match};
209+
use indoc::indoc;
209210

210211
#[test]
211212
fn test_for_file_owner() -> Result<(), Box<dyn Error>> {
@@ -243,17 +244,17 @@ mod tests {
243244

244245
#[test]
245246
fn test_parse_for_team_trims_header() -> Result<(), Box<dyn Error>> {
246-
let codeownership_file = r#"
247-
# STOP! - DO NOT EDIT THIS FILE MANUALLY
248-
# This file was automatically generated by "bin/codeownership validate".
249-
#
250-
# CODEOWNERS is used for GitHub to suggest code/file owners to various GitHub
251-
# teams. This is useful when developers create Pull Requests since the
252-
# code/file owner is notified. Reference GitHub docs for more details:
253-
# https://help.github.com/en/articles/about-code-owners
247+
let codeownership_file = indoc! {"
248+
# STOP! - DO NOT EDIT THIS FILE MANUALLY
249+
# This file was automatically generated by \"bin/codeownership validate\".
250+
#
251+
# CODEOWNERS is used for GitHub to suggest code/file owners to various GitHub
252+
# teams. This is useful when developers create Pull Requests since the
253+
# code/file owner is notified. Reference GitHub docs for more details:
254+
# https://help.github.com/en/articles/about-code-owners
254255
255256
256-
"#;
257+
"};
257258

258259
let team_ownership = parse_for_team("@Bar".to_string(), codeownership_file)?;
259260
assert!(team_ownership.is_empty());
@@ -262,14 +263,14 @@ mod tests {
262263

263264
#[test]
264265
fn test_parse_for_team_includes_owned_globs() -> Result<(), Box<dyn Error>> {
265-
let codeownership_file = r#"
266-
# First Section
267-
/path/to/owned @Foo
268-
/path/to/not/owned @Bar
266+
let codeownership_file = indoc! {"
267+
# First Section
268+
/path/to/owned @Foo
269+
/path/to/not/owned @Bar
269270
270-
# Last Section
271-
/another/owned/path @Foo
272-
"#;
271+
# Last Section
272+
/another/owned/path @Foo
273+
"};
273274

274275
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file)?;
275276
vecs_match(
@@ -290,11 +291,11 @@ mod tests {
290291

291292
#[test]
292293
fn test_parse_for_team_with_partial_team_match() -> Result<(), Box<dyn Error>> {
293-
let codeownership_file = r#"
294-
# First Section
295-
/path/to/owned @Foo
296-
/path/to/not/owned @FooBar
297-
"#;
294+
let codeownership_file = indoc! {"
295+
# First Section
296+
/path/to/owned @Foo
297+
/path/to/not/owned @FooBar
298+
"};
298299

299300
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file)?;
300301
vecs_match(
@@ -309,16 +310,16 @@ mod tests {
309310

310311
#[test]
311312
fn test_parse_for_team_with_trailing_newlines() -> Result<(), Box<dyn Error>> {
312-
let codeownership_file = r#"
313-
# First Section
314-
/path/to/owned @Foo
313+
let codeownership_file = indoc! {"
314+
# First Section
315+
/path/to/owned @Foo
315316
316-
# Last Section
317-
/another/owned/path @Foo
317+
# Last Section
318+
/another/owned/path @Foo
318319
319320
320321
321-
"#;
322+
"};
322323

323324
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file)?;
324325
vecs_match(
@@ -339,9 +340,9 @@ mod tests {
339340

340341
#[test]
341342
fn test_parse_for_team_without_trailing_newline() -> Result<(), Box<dyn Error>> {
342-
let codeownership_file = r#"
343-
# First Section
344-
/path/to/owned @Foo"#;
343+
let codeownership_file = indoc! {"
344+
# First Section
345+
/path/to/owned @Foo"};
345346

346347
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file)?;
347348
vecs_match(
@@ -356,12 +357,12 @@ mod tests {
356357

357358
#[test]
358359
fn test_parse_for_team_with_missing_section_header() -> Result<(), Box<dyn Error>> {
359-
let codeownership_file = r#"
360-
# First Section
361-
/path/to/owned @Foo
360+
let codeownership_file = indoc! {"
361+
# First Section
362+
/path/to/owned @Foo
362363
363-
/another/owned/path @Foo
364-
"#;
364+
/another/owned/path @Foo
365+
"};
365366

366367
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file);
367368
assert!(team_ownership
@@ -371,10 +372,10 @@ mod tests {
371372

372373
#[test]
373374
fn test_parse_for_team_with_malformed_team_line() -> Result<(), Box<dyn Error>> {
374-
let codeownership_file = r#"
375-
# First Section
376-
@Foo
377-
"#;
375+
let codeownership_file = indoc! {"
376+
# First Section
377+
@Foo
378+
"};
378379

379380
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file);
380381
assert!(team_ownership
@@ -384,11 +385,11 @@ mod tests {
384385

385386
#[test]
386387
fn test_parse_for_team_with_invalid_file() -> Result<(), Box<dyn Error>> {
387-
let codeownership_file = r#"
388-
# First Section
389-
# Second Section
390-
path/to/owned @Foo
391-
"#;
388+
let codeownership_file = indoc! {"
389+
# First Section
390+
# Second Section
391+
path/to/owned @Foo
392+
"};
392393
let team_ownership = parse_for_team("@Foo".to_string(), codeownership_file)?;
393394
vecs_match(
394395
&team_ownership,

tests/invalid_project_test.rs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use assert_cmd::prelude::*;
2+
use indoc::indoc;
23
use predicates::prelude::*;
34
use std::{error::Error, process::Command};
45

@@ -10,31 +11,24 @@ fn test_validate() -> Result<(), Box<dyn Error>> {
1011
.arg("validate")
1112
.assert()
1213
.failure()
13-
.stdout(predicate::str::contains(
14-
"CODEOWNERS out of date. Run `codeowners generate` to update the CODEOWNERS file",
15-
))
16-
.stdout(predicate::str::contains(
17-
"Some files are missing ownership\n- ruby/app/models/blockchain.rb\n- ruby/app/unowned.rb",
18-
))
19-
.stdout(predicate::str::contains(
20-
"Found invalid team annotations\n- ruby/app/models/blockchain.rb is referencing an invalid team - 'Web3'",
21-
))
22-
.stdout(predicate::str::contains(
23-
"Code ownership should only be defined for each file in one way. The following files have declared ownership in multiple ways",
24-
))
25-
.stdout(predicate::str::contains(
26-
"gems/payroll_calculator/calculator.rb (owner: Payments, source: Owner annotation at the top of the file)",
27-
))
28-
.stdout(predicate::str::contains(
29-
"gems/payroll_calculator/calculator.rb (owner: Payroll, source: Owner specified in Team YML's `owned_gems`)",
30-
))
31-
.stdout(predicate::str::contains(
32-
"ruby/app/services/multi_owned.rb (owner: Payments, source: Owner annotation at the top of the file)",
33-
))
34-
.stdout(predicate::str::contains(
35-
"ruby/app/services/multi_owned.rb (owner: Payroll, source: Owner specified in `ruby/app/services/.codeowner`",
36-
));
14+
.stdout(predicate::eq(indoc! {"
3715
16+
CODEOWNERS out of date. Run `codeowners generate` to update the CODEOWNERS file
17+
18+
Code ownership should only be defined for each file in one way. The following files have declared ownership in multiple ways
19+
- gems/payroll_calculator/calculator.rb (owner: Payments, source: Owner annotation at the top of the file)
20+
- gems/payroll_calculator/calculator.rb (owner: Payroll, source: Owner specified in Team YML's `owned_gems`)
21+
- ruby/app/services/multi_owned.rb (owner: Payments, source: Owner annotation at the top of the file)
22+
- ruby/app/services/multi_owned.rb (owner: Payroll, source: Owner specified in `ruby/app/services/.codeowner`)
23+
24+
Found invalid team annotations
25+
- ruby/app/models/blockchain.rb is referencing an invalid team - 'Web3'
26+
27+
Some files are missing ownership
28+
- ruby/app/models/blockchain.rb
29+
- ruby/app/unowned.rb
30+
31+
"}));
3832
Ok(())
3933
}
4034

@@ -47,9 +41,10 @@ fn test_for_file() -> Result<(), Box<dyn Error>> {
4741
.arg("ruby/app/models/blockchain.rb")
4842
.assert()
4943
.success()
50-
.stdout(predicate::str::contains("Team: Unowned"))
51-
.stdout(predicate::str::contains("Team YML: Unowned"));
52-
44+
.stdout(predicate::eq(indoc! {"
45+
Team: Unowned
46+
Team YML: Unowned
47+
Description: \n"})); // trailing whitespace
5348
Ok(())
5449
}
5550

@@ -62,15 +57,17 @@ fn test_for_file_multiple_owners() -> Result<(), Box<dyn Error>> {
6257
.arg("ruby/app/services/multi_owned.rb")
6358
.assert()
6459
.success()
65-
.stdout(predicate::str::contains("Error: file is owned by multiple teams!"))
66-
.stdout(predicate::str::contains("Team: Payments"))
67-
.stdout(predicate::str::contains("Team YML: config/teams/payments.yml"))
68-
.stdout(predicate::str::contains("Description: Owner annotation at the top of the file"))
69-
.stdout(predicate::str::contains("Team: Payroll"))
70-
.stdout(predicate::str::contains("Team YML: config/teams/payroll.yml"))
71-
.stdout(predicate::str::contains(
72-
"Description: Owner specified in `ruby/app/services/.codeowner`",
73-
));
74-
60+
.stdout(predicate::str::starts_with("Error: file is owned by multiple teams!"))
61+
// order not static
62+
.stdout(predicate::str::contains(indoc! {"
63+
Team: Payroll
64+
Team YML: config/teams/payroll.yml
65+
Description: Owner specified in `ruby/app/services/.codeowner`
66+
"}))
67+
.stdout(predicate::str::contains(indoc! {"
68+
Team: Payments
69+
Team YML: config/teams/payments.yml
70+
Description: Owner annotation at the top of the file
71+
"}));
7572
Ok(())
7673
}

0 commit comments

Comments
 (0)