Skip to content

Commit a0f98d4

Browse files
john-h-kastner-awsshaobo-he-aws
authored andcommitted
Use insta for snapshot testing of formatter output (#856)
Signed-off-by: John Kastner <[email protected]>
1 parent 370842d commit a0f98d4

File tree

56 files changed

+734
-57
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+734
-57
lines changed

cedar-policy-formatter/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ itertools = "0.12"
1717
smol_str = { version = "0.2", features = ["serde"] }
1818
regex = { version= "1.9.1", features = ["unicode"] }
1919
miette = { version = "7.1.0" }
20+
21+
[dev-dependencies]
22+
insta = { version = "1.38.0", features = ["glob"] }

cedar-policy-formatter/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,18 @@ cedar format -h
3434

3535
Generated documentation for the latest version can be accessed on
3636
[docs.rs](https://docs.rs/cedar-policy-formatter).
37+
38+
## Testing
39+
40+
Tests for this package use [`insta`](https://insta.rs/) for snapshot testing.
41+
Tests are executed with the usual `cargo test`, but, if your changes introduce
42+
a difference in how we format any of the test policies, the tests will fail,
43+
printing a nicely formatted diff as the error message. You can then run `cargo insta review`
44+
to review how formatting has changed. If the change is expected, accept it
45+
and commit the updated snapshot file. Otherwise, reject the change, and fix it
46+
as you would any other failing test case.
47+
48+
You can add new test cases just just by placing a `.cedar` file in the `tests`
49+
directory. The next run of `cargo test` will fail because there is no snapshot
50+
file. Run `cargo insta review` to review the formatted output for the new
51+
tests. Accept and commit the snapshot if it is correct.

cedar-policy-formatter/src/pprint/fmt.rs

Lines changed: 38 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -153,42 +153,10 @@ pub fn policies_str_to_pretty(ps: &str, config: &Config) -> Result<String> {
153153

154154
#[cfg(test)]
155155
mod tests {
156-
use super::*;
157-
const TEST_CONFIG: &Config = &Config {
158-
line_width: 40,
159-
indent_width: 2,
160-
};
161-
162-
#[test]
163-
fn trivial_permit() {
164-
let policy = r#"permit (principal, action, resource);"#;
165-
assert_eq!(policies_str_to_pretty(policy, TEST_CONFIG).unwrap(), policy);
166-
}
156+
use insta::{assert_snapshot, glob, with_settings};
157+
use std::fs;
167158

168-
#[test]
169-
fn trivial_forbid() {
170-
let policy = r#"forbid (principal, action, resource);"#;
171-
assert_eq!(policies_str_to_pretty(policy, TEST_CONFIG).unwrap(), policy);
172-
}
173-
174-
#[test]
175-
fn action_in_set() {
176-
let policy = r#"permit (
177-
principal in UserGroup::"abc",
178-
action in [Action::"viewPhoto", Action::"viewComments"],
179-
resource in Album::"one"
180-
);"#;
181-
assert_eq!(
182-
policies_str_to_pretty(policy, TEST_CONFIG).unwrap(),
183-
r#"permit (
184-
principal in UserGroup::"abc",
185-
action in
186-
[Action::"viewPhoto",
187-
Action::"viewComments"],
188-
resource in Album::"one"
189-
);"#
190-
);
191-
}
159+
use super::*;
192160

193161
#[test]
194162
fn test_soundness_check() {
@@ -235,30 +203,44 @@ mod tests {
235203

236204
#[test]
237205
fn test_format_files() {
238-
use std::fs::read_to_string;
239-
use std::path::Path;
240-
241206
let config = Config {
242207
line_width: 80,
243208
indent_width: 2,
244209
};
245-
let dir_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests");
246-
let pairs = vec![
247-
("test.cedar", "test_formatted.cedar"),
248-
("policies.cedar", "policies_formatted.cedar"),
249-
("is_policies.cedar", "is_policies_formatted.cedar"),
250-
];
251-
for (pf, ef) in pairs {
252-
// editors or cargo run try to append a newline at the end of files
253-
// we should remove them for equality testing
254-
assert_eq!(
255-
policies_str_to_pretty(&read_to_string(dir_path.join(pf)).unwrap(), &config)
256-
.unwrap()
257-
.trim_end_matches('\n'),
258-
read_to_string(dir_path.join(ef))
259-
.unwrap()
260-
.trim_end_matches('\n')
261-
);
262-
}
210+
211+
// This test uses `insta` to test the current output of the formatter
212+
// against the output from prior versions. Run the test as usual with
213+
// `cargo test`.
214+
//
215+
// If it fails, then use `cargo insta review` to review the diff between
216+
// the current output and the snapshot. If the change is expected, you
217+
// can accept the changes to make `insta` update the snapshot which you
218+
// should the commit to the repository.
219+
//
220+
// Add new tests by placing a `.cedar` file in the test directory. The
221+
// next run of `cargo test` will fail. Use `cargo insta review` to check
222+
// the formatted output is expected.
223+
with_settings!(
224+
{ snapshot_path => "../../tests/snapshots/" },
225+
{
226+
glob!("../../tests", "*.cedar", |path| {
227+
let cedar_source = fs::read_to_string(path).unwrap();
228+
let formatted = policies_str_to_pretty(&cedar_source, &config).unwrap();
229+
assert_snapshot!(formatted);
230+
});
231+
}
232+
);
233+
234+
// Also check the CLI sample files.
235+
with_settings!(
236+
{ snapshot_path => "../../tests/cli-snapshots/" },
237+
{
238+
glob!("../../../cedar-policy-cli/sample-data", "**/*.cedar", |path| {
239+
let cedar_source = fs::read_to_string(path).unwrap();
240+
let formatted = policies_str_to_pretty(&cedar_source, &config).unwrap();
241+
assert_snapshot!(formatted);
242+
});
243+
}
244+
)
263245
}
264246
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
permit (
2+
principal in UserGroup::"abc",
3+
action in [Action::"viewPhoto", Action::"viewComments"],
4+
resource in Album::"one"
5+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: cedar-policy-formatter/src/pprint/fmt.rs
3+
expression: formatted
4+
input_file: cedar-policy-cli/sample-data/sandbox_a/policies_1.cedar
5+
---
6+
// Everyone in the group UserGroup::"jane_friends" can view this specific photo
7+
@id("jane's friends view-permission policy")
8+
permit (
9+
principal in UserGroup::"jane_friends",
10+
action == Action::"view",
11+
resource == Photo::"VacationPhoto94.jpg"
12+
);
13+
14+
// but Tim is disallowed from viewing the photo
15+
@id("disallow tim policy")
16+
forbid (
17+
principal == User::"tim",
18+
action,
19+
resource == Photo::"VacationPhoto94.jpg"
20+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: cedar-policy-formatter/src/pprint/fmt.rs
3+
expression: formatted
4+
input_file: cedar-policy-cli/sample-data/sandbox_a/policies_1_bad.cedar
5+
---
6+
// Everyone in the group UserGroup::"jane_friends" can view this specific photo
7+
@id("jane's friends view-permission policy")
8+
permit (
9+
principal in UsrGroup::"jane_friends",
10+
action == Action::"view",
11+
resource == Photo::"VacationPhoto94.jpg"
12+
);
13+
14+
// but Tim is disallowed from viewing the photo
15+
@id("disallow tim policy")
16+
forbid (
17+
principal == User::"tim",
18+
action,
19+
resource == Photo::"VacationPhoto94.jpg"
20+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: cedar-policy-formatter/src/pprint/fmt.rs
3+
expression: formatted
4+
input_file: cedar-policy-cli/sample-data/sandbox_a/policies_2.cedar
5+
---
6+
// Alice can view, edit, or delete any photo in the "jane_vacation" album
7+
@id("alice's access policy")
8+
permit (
9+
principal == User::"alice",
10+
action in [Action::"view", Action::"edit", Action::"delete"],
11+
resource in Album::"jane_vacation"
12+
);
13+
14+
// Bob can only view things in the "jane_vacation" album
15+
@id("bob's view policy")
16+
permit (
17+
principal == User::"bob",
18+
action == Action::"view",
19+
resource in Album::"jane_vacation"
20+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
source: cedar-policy-formatter/src/pprint/fmt.rs
3+
expression: formatted
4+
input_file: cedar-policy-cli/sample-data/sandbox_a/policies_3.cedar
5+
---
6+
// Everyone can view the photos in the "jane_vacation" album
7+
// (and list the photos in the album)
8+
@id("jane_vacation public")
9+
permit (
10+
principal,
11+
action in [Action::"view", Action::"listPhotos"],
12+
resource in Album::"jane_vacation"
13+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
source: cedar-policy-formatter/src/pprint/fmt.rs
3+
expression: formatted
4+
input_file: cedar-policy-cli/sample-data/sandbox_b/policies_4.cedar
5+
---
6+
// Only members of the HardwareEngineering department with job level >= 5 can
7+
// view photos in device_prototypes
8+
@id("prototypes access policy")
9+
permit (
10+
principal,
11+
action == Action::"view",
12+
resource in Album::"device_prototypes"
13+
)
14+
when
15+
{ principal.department == "HardwareEngineering" && principal.jobLevel >= 5 };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
source: cedar-policy-formatter/src/pprint/fmt.rs
3+
expression: formatted
4+
input_file: cedar-policy-cli/sample-data/sandbox_b/policies_5.cedar
5+
---
6+
// Alice's friends can view all of her photos
7+
@id("alice's friends view policy")
8+
permit (
9+
principal in UserGroup::"alice_friends",
10+
action == Action::"view",
11+
resource in Account::"alice"
12+
);
13+
14+
// but, as a general rule, anything marked private can only be viewed by the
15+
// account owner
16+
@id("privacy rule")
17+
forbid (principal, action, resource)
18+
when { resource.private }
19+
unless { resource.account has owner && resource.account.owner == principal };

0 commit comments

Comments
 (0)