Skip to content

Commit cdf5a42

Browse files
committed
test(playlist): make absolute-path fixtures cross-platform
The playlist tests hardcoded POSIX absolute paths like "/music/song.mod". A leading slash is not absolute on Windows (no drive letter), so on the Windows CI runner these were treated as relative and anchored to the current drive, failing 10 assertions. Route the fixtures through an abs_path() helper that prepends a drive prefix on Windows and is a no-op on Unix, keeping Unix behaviour identical while making the suite pass on Windows.
1 parent b0c4298 commit cdf5a42

1 file changed

Lines changed: 54 additions & 35 deletions

File tree

src/playlist.rs

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,24 @@ mod tests {
204204
use super::*;
205205
use std::fs;
206206

207+
/// Build a platform-absolute path from POSIX-style components. A leading
208+
/// `/` is absolute on Unix but *not* on Windows (which wants a drive
209+
/// prefix), so these fixtures would otherwise be treated as relative there.
210+
/// On Unix the path is returned unchanged.
211+
fn abs_path(posix: &str) -> PathBuf {
212+
let rel = posix.trim_start_matches('/');
213+
if cfg!(windows) {
214+
PathBuf::from(format!("C:\\{}", rel.replace('/', "\\")))
215+
} else {
216+
PathBuf::from(format!("/{rel}"))
217+
}
218+
}
219+
207220
// ── from_files ──────────────────────────────────────────────────────────
208221

209222
#[test]
210223
fn from_files_absolute_stays_absolute() {
211-
let abs = PathBuf::from("/tmp/song.mod");
224+
let abs = abs_path("/tmp/song.mod");
212225
let pl = Playlist::from_files(vec![abs.clone()]);
213226
assert_eq!(pl.entries[0], abs);
214227
assert!(pl.path.is_none());
@@ -235,16 +248,22 @@ mod tests {
235248
fn load_skips_comments_and_blank_lines() {
236249
let dir = tempfile::tempdir().unwrap();
237250
let pl_path = dir.path().join("list.m3u");
251+
let song = abs_path("/abs/song.mod");
252+
let other = abs_path("/abs/other.xm");
238253
fs::write(
239254
&pl_path,
240-
"#EXTM3U\n# a comment\n\n/abs/song.mod\n\n# another\n/abs/other.xm\n",
255+
format!(
256+
"#EXTM3U\n# a comment\n\n{}\n\n# another\n{}\n",
257+
song.display(),
258+
other.display()
259+
),
241260
)
242261
.unwrap();
243262

244263
let pl = Playlist::load(pl_path).unwrap();
245264
assert_eq!(pl.entries.len(), 2);
246-
assert_eq!(pl.entries[0], PathBuf::from("/abs/song.mod"));
247-
assert_eq!(pl.entries[1], PathBuf::from("/abs/other.xm"));
265+
assert_eq!(pl.entries[0], song);
266+
assert_eq!(pl.entries[1], other);
248267
}
249268

250269
#[test]
@@ -262,31 +281,32 @@ mod tests {
262281
fn load_keeps_absolute_paths() {
263282
let dir = tempfile::tempdir().unwrap();
264283
let pl_path = dir.path().join("list.m3u");
265-
fs::write(&pl_path, "/music/song.mod\n").unwrap();
284+
let song = abs_path("/music/song.mod");
285+
fs::write(&pl_path, format!("{}\n", song.display())).unwrap();
266286

267287
let pl = Playlist::load(pl_path).unwrap();
268-
assert_eq!(pl.entries[0], PathBuf::from("/music/song.mod"));
288+
assert_eq!(pl.entries[0], song);
269289
}
270290

271291
// ── navigation ──────────────────────────────────────────────────────────
272292

273293
fn three_entry_playlist() -> Playlist {
274294
Playlist::from_files(vec![
275-
PathBuf::from("/a.mod"),
276-
PathBuf::from("/b.mod"),
277-
PathBuf::from("/c.mod"),
295+
abs_path("/a.mod"),
296+
abs_path("/b.mod"),
297+
abs_path("/c.mod"),
278298
])
279299
}
280300

281301
#[test]
282302
fn next_after_returns_following_entry() {
283303
let pl = three_entry_playlist();
284304
assert_eq!(
285-
pl.next_after(Path::new("/a.mod")),
305+
pl.next_after(&abs_path("/a.mod")),
286306
Some(pl.entries[1].clone())
287307
);
288308
assert_eq!(
289-
pl.next_after(Path::new("/b.mod")),
309+
pl.next_after(&abs_path("/b.mod")),
290310
Some(pl.entries[2].clone())
291311
);
292312
}
@@ -307,11 +327,11 @@ mod tests {
307327
fn prev_before_returns_preceding_entry() {
308328
let pl = three_entry_playlist();
309329
assert_eq!(
310-
pl.prev_before(Path::new("/b.mod")),
330+
pl.prev_before(&abs_path("/b.mod")),
311331
Some(pl.entries[0].clone())
312332
);
313333
assert_eq!(
314-
pl.prev_before(Path::new("/c.mod")),
334+
pl.prev_before(&abs_path("/c.mod")),
315335
Some(pl.entries[1].clone())
316336
);
317337
}
@@ -348,9 +368,8 @@ mod tests {
348368

349369
#[test]
350370
fn shuffle_anchors_on_the_current_track() {
351-
let mut pl =
352-
Playlist::from_files((0..16).map(|i| PathBuf::from(format!("/{i}.xm"))).collect());
353-
let anchor = PathBuf::from("/7.xm");
371+
let mut pl = Playlist::from_files((0..16).map(|i| abs_path(&format!("/{i}.xm"))).collect());
372+
let anchor = abs_path("/7.xm");
354373
pl.set_shuffle(true, Some(&anchor));
355374
// The anchor becomes the head so playback continues from it.
356375
assert_eq!(pl.start(), Some(&anchor));
@@ -359,28 +378,22 @@ mod tests {
359378
#[test]
360379
fn unshuffle_restores_sequential_order() {
361380
let mut pl = Playlist::from_files(vec![
362-
PathBuf::from("/a.xm"),
363-
PathBuf::from("/b.xm"),
364-
PathBuf::from("/c.xm"),
381+
abs_path("/a.xm"),
382+
abs_path("/b.xm"),
383+
abs_path("/c.xm"),
365384
]);
366385
pl.set_shuffle(true, None);
367386
pl.set_shuffle(false, None);
368387
assert!(!pl.is_shuffled());
369-
assert_eq!(
370-
pl.next_after(Path::new("/a.xm")),
371-
Some(PathBuf::from("/b.xm"))
372-
);
388+
assert_eq!(pl.next_after(&abs_path("/a.xm")), Some(abs_path("/b.xm")));
373389
}
374390

375391
#[test]
376392
fn push_keeps_order_consistent() {
377-
let mut pl = Playlist::from_files(vec![PathBuf::from("/a.xm")]);
378-
pl.push(PathBuf::from("/b.xm"));
393+
let mut pl = Playlist::from_files(vec![abs_path("/a.xm")]);
394+
pl.push(abs_path("/b.xm"));
379395
assert_eq!(pl.len(), 2);
380-
assert_eq!(
381-
pl.next_after(Path::new("/a.xm")),
382-
Some(PathBuf::from("/b.xm"))
383-
);
396+
assert_eq!(pl.next_after(&abs_path("/a.xm")), Some(abs_path("/b.xm")));
384397
}
385398

386399
#[test]
@@ -436,10 +449,11 @@ mod tests {
436449
fn file_contains_detects_absolute_entry() {
437450
let dir = tempfile::tempdir().unwrap();
438451
let pl_path = dir.path().join("list.m3u");
439-
fs::write(&pl_path, "#EXTM3U\n/music/song.mod\n").unwrap();
452+
let song = abs_path("/music/song.mod");
453+
fs::write(&pl_path, format!("#EXTM3U\n{}\n", song.display())).unwrap();
440454

441-
assert!(file_contains(Path::new("/music/song.mod"), &pl_path));
442-
assert!(!file_contains(Path::new("/music/other.mod"), &pl_path));
455+
assert!(file_contains(&song, &pl_path));
456+
assert!(!file_contains(&abs_path("/music/other.mod"), &pl_path));
443457
}
444458

445459
#[test]
@@ -456,10 +470,15 @@ mod tests {
456470
fn file_contains_skips_comments_and_blank_lines() {
457471
let dir = tempfile::tempdir().unwrap();
458472
let pl_path = dir.path().join("list.m3u");
459-
fs::write(&pl_path, "#EXTM3U\n# /commented.mod\n\n/real.mod\n").unwrap();
473+
let real = abs_path("/real.mod");
474+
fs::write(
475+
&pl_path,
476+
format!("#EXTM3U\n# /commented.mod\n\n{}\n", real.display()),
477+
)
478+
.unwrap();
460479

461-
assert!(!file_contains(Path::new("/commented.mod"), &pl_path));
462-
assert!(file_contains(Path::new("/real.mod"), &pl_path));
480+
assert!(!file_contains(&abs_path("/commented.mod"), &pl_path));
481+
assert!(file_contains(&real, &pl_path));
463482
}
464483

465484
#[test]

0 commit comments

Comments
 (0)