|
| 1 | +use crate::TestFiles; |
| 2 | +use std::fs; |
| 3 | + |
| 4 | +/// Test for issue #777: Insta "source" in snapshot is full absolute path when workspace is not parent |
| 5 | +#[test] |
| 6 | +fn test_workspace_source_path_issue_777() { |
| 7 | + // Create a workspace structure where project is not a child of workspace |
| 8 | + // This reproduces the exact issue from #777 |
| 9 | + let test_project = TestFiles::new() |
| 10 | + .add_file( |
| 11 | + "workspace/Cargo.toml", |
| 12 | + r#" |
| 13 | +[workspace] |
| 14 | +resolver = "2" |
| 15 | +members = ["../project1"] |
| 16 | +"# |
| 17 | + .to_string(), |
| 18 | + ) |
| 19 | + .add_file( |
| 20 | + "project1/Cargo.toml", |
| 21 | + r#" |
| 22 | +[package] |
| 23 | +name = "project1" |
| 24 | +version = "0.1.0" |
| 25 | +edition = "2021" |
| 26 | +
|
| 27 | +workspace = "../workspace" |
| 28 | +
|
| 29 | +[dependencies] |
| 30 | +insta = { path = '$PROJECT_PATH', features = ["yaml"] } |
| 31 | +"# |
| 32 | + .to_string(), |
| 33 | + ) |
| 34 | + .add_file( |
| 35 | + "project1/src/lib.rs", |
| 36 | + r#" |
| 37 | +#[test] |
| 38 | +fn test_something() { |
| 39 | + insta::assert_yaml_snapshot!(vec![1, 2, 3]); |
| 40 | +} |
| 41 | +"# |
| 42 | + .to_string(), |
| 43 | + ) |
| 44 | + .create_project(); |
| 45 | + |
| 46 | + // Run test to create snapshot from within project1 directory |
| 47 | + // This should trigger the issue where source path becomes absolute |
| 48 | + let output = test_project |
| 49 | + .insta_cmd() |
| 50 | + .current_dir(test_project.workspace_dir.join("project1")) |
| 51 | + // Set workspace root to the actual workspace directory |
| 52 | + .env( |
| 53 | + "INSTA_WORKSPACE_ROOT", |
| 54 | + test_project.workspace_dir.join("workspace"), |
| 55 | + ) |
| 56 | + .args(["test", "--accept"]) |
| 57 | + .output() |
| 58 | + .unwrap(); |
| 59 | + |
| 60 | + assert!(output.status.success()); |
| 61 | + |
| 62 | + // Read the generated snapshot |
| 63 | + let snapshot_path = test_project |
| 64 | + .workspace_dir |
| 65 | + .join("project1/src/snapshots/project1__something.snap"); |
| 66 | + |
| 67 | + let snapshot_content = fs::read_to_string(&snapshot_path).unwrap(); |
| 68 | + |
| 69 | + // Parse the snapshot to check the source field |
| 70 | + let source_line = snapshot_content |
| 71 | + .lines() |
| 72 | + .find(|line| line.starts_with("source:")) |
| 73 | + .expect("source line not found"); |
| 74 | + |
| 75 | + let source_path = source_line |
| 76 | + .strip_prefix("source: ") |
| 77 | + .expect("invalid source line") |
| 78 | + .trim() |
| 79 | + .trim_matches('"'); |
| 80 | + |
| 81 | + // The source path should be relative and start with ../ (since workspace and project are siblings) |
| 82 | + assert!( |
| 83 | + source_path.starts_with("../"), |
| 84 | + "Source path should be relative starting with '../', but got: {}", |
| 85 | + source_path |
| 86 | + ); |
| 87 | + |
| 88 | + // The path should be exactly ../project1/src/lib.rs |
| 89 | + assert_eq!( |
| 90 | + source_path, "../project1/src/lib.rs", |
| 91 | + "Expected simplified relative path" |
| 92 | + ); |
| 93 | +} |
| 94 | + |
| 95 | +/// Test that the fix works with a more complex workspace structure |
| 96 | +#[test] |
| 97 | +fn test_workspace_source_path_complex() { |
| 98 | + // Create a complex workspace structure |
| 99 | + let test_project = TestFiles::new() |
| 100 | + .add_file( |
| 101 | + "code/workspace/Cargo.toml", |
| 102 | + r#" |
| 103 | +[workspace] |
| 104 | +resolver = "2" |
| 105 | +members = ["../../projects/app1", "../../projects/app2"] |
| 106 | +"# |
| 107 | + .to_string(), |
| 108 | + ) |
| 109 | + .add_file( |
| 110 | + "projects/app1/Cargo.toml", |
| 111 | + r#" |
| 112 | +[package] |
| 113 | +name = "app1" |
| 114 | +version = "0.1.0" |
| 115 | +edition = "2021" |
| 116 | +
|
| 117 | +workspace = "../../code/workspace" |
| 118 | +
|
| 119 | +[dependencies] |
| 120 | +insta = { path = '$PROJECT_PATH', features = ["yaml"] } |
| 121 | +"# |
| 122 | + .to_string(), |
| 123 | + ) |
| 124 | + .add_file( |
| 125 | + "projects/app1/src/lib.rs", |
| 126 | + r#" |
| 127 | +#[test] |
| 128 | +fn test_app1() { |
| 129 | + insta::assert_yaml_snapshot!(vec!["app1"]); |
| 130 | +} |
| 131 | +"# |
| 132 | + .to_string(), |
| 133 | + ) |
| 134 | + .add_file( |
| 135 | + "projects/app2/Cargo.toml", |
| 136 | + r#" |
| 137 | +[package] |
| 138 | +name = "app2" |
| 139 | +version = "0.1.0" |
| 140 | +edition = "2021" |
| 141 | +
|
| 142 | +workspace = "../../code/workspace" |
| 143 | +
|
| 144 | +[dependencies] |
| 145 | +insta = { path = '$PROJECT_PATH', features = ["yaml"] } |
| 146 | +"# |
| 147 | + .to_string(), |
| 148 | + ) |
| 149 | + .add_file( |
| 150 | + "projects/app2/src/lib.rs", |
| 151 | + r#" |
| 152 | +#[test] |
| 153 | +fn test_app2() { |
| 154 | + insta::assert_yaml_snapshot!(vec!["app2"]); |
| 155 | +} |
| 156 | +"# |
| 157 | + .to_string(), |
| 158 | + ) |
| 159 | + .create_project(); |
| 160 | + |
| 161 | + // Run tests for both projects |
| 162 | + let output1 = test_project |
| 163 | + .insta_cmd() |
| 164 | + .current_dir(test_project.workspace_dir.join("projects/app1")) |
| 165 | + .args(["test", "--accept"]) |
| 166 | + .output() |
| 167 | + .unwrap(); |
| 168 | + |
| 169 | + assert!(output1.status.success()); |
| 170 | + |
| 171 | + let output2 = test_project |
| 172 | + .insta_cmd() |
| 173 | + .current_dir(test_project.workspace_dir.join("projects/app2")) |
| 174 | + .args(["test", "--accept"]) |
| 175 | + .output() |
| 176 | + .unwrap(); |
| 177 | + |
| 178 | + assert!(output2.status.success()); |
| 179 | + |
| 180 | + // Check both snapshots |
| 181 | + let snapshot1_path = test_project |
| 182 | + .workspace_dir |
| 183 | + .join("projects/app1/src/snapshots/app1__app1.snap"); |
| 184 | + let snapshot1_content = fs::read_to_string(&snapshot1_path).unwrap(); |
| 185 | + |
| 186 | + let snapshot2_path = test_project |
| 187 | + .workspace_dir |
| 188 | + .join("projects/app2/src/snapshots/app2__app2.snap"); |
| 189 | + let snapshot2_content = fs::read_to_string(&snapshot2_path).unwrap(); |
| 190 | + |
| 191 | + // Neither snapshot should contain absolute paths |
| 192 | + assert!( |
| 193 | + !snapshot1_content.contains(&test_project.workspace_dir.to_string_lossy().to_string()), |
| 194 | + "App1 snapshot contains absolute path" |
| 195 | + ); |
| 196 | + assert!( |
| 197 | + !snapshot2_content.contains(&test_project.workspace_dir.to_string_lossy().to_string()), |
| 198 | + "App2 snapshot contains absolute path" |
| 199 | + ); |
| 200 | + |
| 201 | + // Both should have relative paths |
| 202 | + assert!( |
| 203 | + snapshot1_content.contains("source: \"../../projects/app1/src/lib.rs\""), |
| 204 | + "App1 snapshot source is not the expected relative path. Got:\n{}", |
| 205 | + snapshot1_content |
| 206 | + ); |
| 207 | + assert!( |
| 208 | + snapshot2_content.contains("source: \"../../projects/app2/src/lib.rs\""), |
| 209 | + "App2 snapshot source is not the expected relative path. Got:\n{}", |
| 210 | + snapshot2_content |
| 211 | + ); |
| 212 | +} |
0 commit comments