• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loot / loot-condition-interpreter / 14679793593

26 Apr 2025 09:10AM UTC coverage: 91.6% (+0.02%) from 91.583%
14679793593

push

github

Ortham
Deny a lot of extra lints and fix their errors

337 of 376 new or added lines in 10 files covered. (89.63%)

111 existing lines in 7 files now uncovered.

4907 of 5357 relevant lines covered (91.6%)

15.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.55
/src/function/path.rs
1
use std::{
2
    ffi::OsStr,
3
    path::{Path, PathBuf},
4
};
5

6
use crate::{GameType, State};
7

8
const GHOST_EXTENSION: &str = "ghost";
9
const GHOST_EXTENSION_WITH_PERIOD: &str = ".ghost";
10

11
fn is_unghosted_plugin_file_extension(game_type: GameType, extension: &OsStr) -> bool {
162✔
12
    extension.eq_ignore_ascii_case("esp")
162✔
13
        || extension.eq_ignore_ascii_case("esm")
137✔
14
        || (game_type.supports_light_plugins() && extension.eq_ignore_ascii_case("esl"))
90✔
15
        || (game_type == GameType::OpenMW
86✔
16
            && (extension.eq_ignore_ascii_case("omwaddon")
7✔
17
                || extension.eq_ignore_ascii_case("omwgame")
6✔
18
                || extension.eq_ignore_ascii_case("omwscripts")))
5✔
19
}
162✔
20

21
fn has_unghosted_plugin_file_extension(game_type: GameType, path: &Path) -> bool {
101✔
22
    match path.extension() {
101✔
23
        Some(ext) => is_unghosted_plugin_file_extension(game_type, ext),
72✔
24
        _ => false,
29✔
25
    }
26
}
101✔
27

28
pub(super) fn has_plugin_file_extension(game_type: GameType, path: &Path) -> bool {
14✔
29
    match path.extension() {
14✔
30
        Some(ext)
3✔
31
            if game_type.allows_ghosted_plugins() && ext.eq_ignore_ascii_case(GHOST_EXTENSION) =>
13✔
32
        {
3✔
33
            path.file_stem()
3✔
34
                .is_some_and(|s| has_unghosted_plugin_file_extension(game_type, Path::new(s)))
3✔
35
        }
36
        Some(ext) => is_unghosted_plugin_file_extension(game_type, ext),
10✔
37
        _ => false,
1✔
38
    }
39
}
14✔
40

41
fn add_ghost_extension(path: &Path) -> PathBuf {
10✔
42
    match path.extension() {
10✔
43
        Some(e) => {
9✔
44
            let mut new_extension = e.to_os_string();
9✔
45
            new_extension.push(GHOST_EXTENSION_WITH_PERIOD);
9✔
46
            path.with_extension(&new_extension)
9✔
47
        }
48
        None => path.with_extension(GHOST_EXTENSION),
1✔
49
    }
50
}
10✔
51

52
pub(super) fn normalise_file_name(game_type: GameType, name: &OsStr) -> &OsStr {
160✔
53
    if !game_type.allows_ghosted_plugins() {
160✔
54
        return name;
1✔
55
    }
159✔
56

159✔
57
    let path = Path::new(name);
159✔
58
    if path
159✔
59
        .extension()
159✔
60
        .is_some_and(|s| s.eq_ignore_ascii_case(GHOST_EXTENSION))
159✔
61
    {
62
        // name ends in .ghost, trim it and then check the file extension.
63
        if let Some(stem) = path.file_stem() {
5✔
64
            if has_unghosted_plugin_file_extension(game_type, Path::new(stem)) {
5✔
65
                return stem;
4✔
66
            }
1✔
UNCOV
67
        }
×
68
    }
154✔
69

70
    name
155✔
71
}
160✔
72

73
pub(super) fn resolve_path_in_parent_paths<'a>(
91✔
74
    path: &Path,
91✔
75
    parent_paths: impl Iterator<Item = &'a PathBuf>,
91✔
76
    try_with_ghost_extension: bool,
91✔
77
) -> Option<PathBuf> {
91✔
78
    for parent_path in parent_paths {
92✔
79
        let joined_path = parent_path.join(path);
5✔
80

5✔
81
        if joined_path.exists() {
5✔
82
            return Some(joined_path);
4✔
83
        }
1✔
84

1✔
85
        if try_with_ghost_extension {
1✔
86
            let ghosted_path = add_ghost_extension(&joined_path);
1✔
87

1✔
88
            if ghosted_path.exists() {
1✔
89
                return Some(ghosted_path);
×
90
            }
1✔
UNCOV
91
        }
×
92
    }
93

94
    None
87✔
95
}
91✔
96

97
pub(super) fn resolve_path(state: &State, path: &Path) -> PathBuf {
91✔
98
    let try_with_ghost_extension = state.game_type.allows_ghosted_plugins()
91✔
99
        && has_unghosted_plugin_file_extension(state.game_type, path);
89✔
100

101
    // OpenMW uses the last data directory that contains a matching path, with
102
    // the main data path being listed first, while for other games the first
103
    // additional data path that contains a matching path is used, and then the
104
    // main data path is checked.
105
    let result = match state.game_type {
91✔
106
        GameType::OpenMW => resolve_path_in_parent_paths(
2✔
107
            path,
2✔
108
            state.additional_data_paths.iter().rev(),
2✔
109
            try_with_ghost_extension,
2✔
110
        ),
2✔
111
        _ => resolve_path_in_parent_paths(
89✔
112
            path,
89✔
113
            state.additional_data_paths.iter(),
89✔
114
            try_with_ghost_extension,
89✔
115
        ),
89✔
116
    };
117

118
    if let Some(path) = result {
91✔
119
        return path;
4✔
120
    }
87✔
121

87✔
122
    // Now check the main data path.
87✔
123
    let joined_path = state.data_path.join(path);
87✔
124

87✔
125
    if !joined_path.exists() && try_with_ghost_extension {
87✔
126
        add_ghost_extension(&joined_path)
7✔
127
    } else {
128
        joined_path
80✔
129
    }
130
}
91✔
131

132
#[cfg(test)]
133
mod tests {
134
    use std::fs::create_dir_all;
135

136
    use super::*;
137

138
    #[test]
139
    fn is_unghosted_plugin_file_extension_should_be_true_for_esp_for_all_game_types() {
1✔
140
        let extension = OsStr::new("Esp");
1✔
141

1✔
142
        assert!(is_unghosted_plugin_file_extension(
1✔
143
            GameType::OpenMW,
1✔
144
            extension
1✔
145
        ));
1✔
146
        assert!(is_unghosted_plugin_file_extension(
1✔
147
            GameType::Morrowind,
1✔
148
            extension
1✔
149
        ));
1✔
150
        assert!(is_unghosted_plugin_file_extension(
1✔
151
            GameType::Oblivion,
1✔
152
            extension
1✔
153
        ));
1✔
154
        assert!(is_unghosted_plugin_file_extension(
1✔
155
            GameType::Skyrim,
1✔
156
            extension
1✔
157
        ));
1✔
158
        assert!(is_unghosted_plugin_file_extension(
1✔
159
            GameType::SkyrimSE,
1✔
160
            extension
1✔
161
        ));
1✔
162
        assert!(is_unghosted_plugin_file_extension(
1✔
163
            GameType::SkyrimVR,
1✔
164
            extension
1✔
165
        ));
1✔
166
        assert!(is_unghosted_plugin_file_extension(
1✔
167
            GameType::Fallout3,
1✔
168
            extension
1✔
169
        ));
1✔
170
        assert!(is_unghosted_plugin_file_extension(
1✔
171
            GameType::FalloutNV,
1✔
172
            extension
1✔
173
        ));
1✔
174
        assert!(is_unghosted_plugin_file_extension(
1✔
175
            GameType::Fallout4,
1✔
176
            extension
1✔
177
        ));
1✔
178
        assert!(is_unghosted_plugin_file_extension(
1✔
179
            GameType::Fallout4VR,
1✔
180
            extension
1✔
181
        ));
1✔
182
    }
1✔
183

184
    #[test]
185
    fn is_unghosted_plugin_file_extension_should_be_true_for_esm_for_all_game_types() {
1✔
186
        let extension = OsStr::new("Esm");
1✔
187

1✔
188
        assert!(is_unghosted_plugin_file_extension(
1✔
189
            GameType::OpenMW,
1✔
190
            extension
1✔
191
        ));
1✔
192
        assert!(is_unghosted_plugin_file_extension(
1✔
193
            GameType::Morrowind,
1✔
194
            extension
1✔
195
        ));
1✔
196
        assert!(is_unghosted_plugin_file_extension(
1✔
197
            GameType::Oblivion,
1✔
198
            extension
1✔
199
        ));
1✔
200
        assert!(is_unghosted_plugin_file_extension(
1✔
201
            GameType::Skyrim,
1✔
202
            extension
1✔
203
        ));
1✔
204
        assert!(is_unghosted_plugin_file_extension(
1✔
205
            GameType::SkyrimSE,
1✔
206
            extension
1✔
207
        ));
1✔
208
        assert!(is_unghosted_plugin_file_extension(
1✔
209
            GameType::SkyrimVR,
1✔
210
            extension
1✔
211
        ));
1✔
212
        assert!(is_unghosted_plugin_file_extension(
1✔
213
            GameType::Fallout3,
1✔
214
            extension
1✔
215
        ));
1✔
216
        assert!(is_unghosted_plugin_file_extension(
1✔
217
            GameType::FalloutNV,
1✔
218
            extension
1✔
219
        ));
1✔
220
        assert!(is_unghosted_plugin_file_extension(
1✔
221
            GameType::Fallout4,
1✔
222
            extension
1✔
223
        ));
1✔
224
        assert!(is_unghosted_plugin_file_extension(
1✔
225
            GameType::Fallout4VR,
1✔
226
            extension
1✔
227
        ));
1✔
228
    }
1✔
229

230
    #[test]
231
    fn is_unghosted_plugin_file_extension_should_be_true_for_esl_for_tes5se_tes5vr_fo4_and_fo4vr() {
1✔
232
        let extension = OsStr::new("Esl");
1✔
233

1✔
234
        assert!(is_unghosted_plugin_file_extension(
1✔
235
            GameType::SkyrimSE,
1✔
236
            extension
1✔
237
        ));
1✔
238
        assert!(is_unghosted_plugin_file_extension(
1✔
239
            GameType::SkyrimVR,
1✔
240
            extension
1✔
241
        ));
1✔
242
        assert!(is_unghosted_plugin_file_extension(
1✔
243
            GameType::Fallout4,
1✔
244
            extension
1✔
245
        ));
1✔
246
        assert!(is_unghosted_plugin_file_extension(
1✔
247
            GameType::Fallout4VR,
1✔
248
            extension
1✔
249
        ));
1✔
250
    }
1✔
251

252
    #[test]
253
    fn is_unghosted_plugin_file_extension_should_be_false_for_esl_for_tes3_to_5_fo3_and_fonv() {
1✔
254
        let extension = OsStr::new("Esl");
1✔
255

1✔
256
        assert!(!is_unghosted_plugin_file_extension(
1✔
257
            GameType::OpenMW,
1✔
258
            extension
1✔
259
        ));
1✔
260
        assert!(!is_unghosted_plugin_file_extension(
1✔
261
            GameType::Morrowind,
1✔
262
            extension
1✔
263
        ));
1✔
264
        assert!(!is_unghosted_plugin_file_extension(
1✔
265
            GameType::Oblivion,
1✔
266
            extension
1✔
267
        ));
1✔
268
        assert!(!is_unghosted_plugin_file_extension(
1✔
269
            GameType::Skyrim,
1✔
270
            extension
1✔
271
        ));
1✔
272
        assert!(!is_unghosted_plugin_file_extension(
1✔
273
            GameType::Fallout3,
1✔
274
            extension
1✔
275
        ));
1✔
276
        assert!(!is_unghosted_plugin_file_extension(
1✔
277
            GameType::FalloutNV,
1✔
278
            extension
1✔
279
        ));
1✔
280
    }
1✔
281

282
    #[test]
283
    fn is_unghosted_plugin_file_extension_should_be_true_for_omwaddon_and_only_openmw() {
1✔
284
        let extension = OsStr::new("omwaddon");
1✔
285

1✔
286
        assert!(is_unghosted_plugin_file_extension(
1✔
287
            GameType::OpenMW,
1✔
288
            extension
1✔
289
        ));
1✔
290

291
        assert!(!is_unghosted_plugin_file_extension(
1✔
292
            GameType::Morrowind,
1✔
293
            extension
1✔
294
        ));
1✔
295
        assert!(!is_unghosted_plugin_file_extension(
1✔
296
            GameType::Oblivion,
1✔
297
            extension
1✔
298
        ));
1✔
299
        assert!(!is_unghosted_plugin_file_extension(
1✔
300
            GameType::Skyrim,
1✔
301
            extension
1✔
302
        ));
1✔
303
        assert!(!is_unghosted_plugin_file_extension(
1✔
304
            GameType::SkyrimSE,
1✔
305
            extension
1✔
306
        ));
1✔
307
        assert!(!is_unghosted_plugin_file_extension(
1✔
308
            GameType::SkyrimVR,
1✔
309
            extension
1✔
310
        ));
1✔
311
        assert!(!is_unghosted_plugin_file_extension(
1✔
312
            GameType::Fallout3,
1✔
313
            extension
1✔
314
        ));
1✔
315
        assert!(!is_unghosted_plugin_file_extension(
1✔
316
            GameType::FalloutNV,
1✔
317
            extension
1✔
318
        ));
1✔
319
        assert!(!is_unghosted_plugin_file_extension(
1✔
320
            GameType::Fallout4,
1✔
321
            extension
1✔
322
        ));
1✔
323
        assert!(!is_unghosted_plugin_file_extension(
1✔
324
            GameType::Fallout4VR,
1✔
325
            extension
1✔
326
        ));
1✔
327
    }
1✔
328

329
    #[test]
330
    fn is_unghosted_plugin_file_extension_should_be_true_for_omwgame_and_only_openmw() {
1✔
331
        let extension = OsStr::new("omwgame");
1✔
332

1✔
333
        assert!(is_unghosted_plugin_file_extension(
1✔
334
            GameType::OpenMW,
1✔
335
            extension
1✔
336
        ));
1✔
337

338
        assert!(!is_unghosted_plugin_file_extension(
1✔
339
            GameType::Morrowind,
1✔
340
            extension
1✔
341
        ));
1✔
342
        assert!(!is_unghosted_plugin_file_extension(
1✔
343
            GameType::Oblivion,
1✔
344
            extension
1✔
345
        ));
1✔
346
        assert!(!is_unghosted_plugin_file_extension(
1✔
347
            GameType::Skyrim,
1✔
348
            extension
1✔
349
        ));
1✔
350
        assert!(!is_unghosted_plugin_file_extension(
1✔
351
            GameType::SkyrimSE,
1✔
352
            extension
1✔
353
        ));
1✔
354
        assert!(!is_unghosted_plugin_file_extension(
1✔
355
            GameType::SkyrimVR,
1✔
356
            extension
1✔
357
        ));
1✔
358
        assert!(!is_unghosted_plugin_file_extension(
1✔
359
            GameType::Fallout3,
1✔
360
            extension
1✔
361
        ));
1✔
362
        assert!(!is_unghosted_plugin_file_extension(
1✔
363
            GameType::FalloutNV,
1✔
364
            extension
1✔
365
        ));
1✔
366
        assert!(!is_unghosted_plugin_file_extension(
1✔
367
            GameType::Fallout4,
1✔
368
            extension
1✔
369
        ));
1✔
370
        assert!(!is_unghosted_plugin_file_extension(
1✔
371
            GameType::Fallout4VR,
1✔
372
            extension
1✔
373
        ));
1✔
374
    }
1✔
375

376
    #[test]
377
    fn is_unghosted_plugin_file_extension_should_be_true_for_omwscripts_and_only_openmw() {
1✔
378
        let extension = OsStr::new("omwscripts");
1✔
379

1✔
380
        assert!(is_unghosted_plugin_file_extension(
1✔
381
            GameType::OpenMW,
1✔
382
            extension
1✔
383
        ));
1✔
384

385
        assert!(!is_unghosted_plugin_file_extension(
1✔
386
            GameType::Morrowind,
1✔
387
            extension
1✔
388
        ));
1✔
389
        assert!(!is_unghosted_plugin_file_extension(
1✔
390
            GameType::Oblivion,
1✔
391
            extension
1✔
392
        ));
1✔
393
        assert!(!is_unghosted_plugin_file_extension(
1✔
394
            GameType::Skyrim,
1✔
395
            extension
1✔
396
        ));
1✔
397
        assert!(!is_unghosted_plugin_file_extension(
1✔
398
            GameType::SkyrimSE,
1✔
399
            extension
1✔
400
        ));
1✔
401
        assert!(!is_unghosted_plugin_file_extension(
1✔
402
            GameType::SkyrimVR,
1✔
403
            extension
1✔
404
        ));
1✔
405
        assert!(!is_unghosted_plugin_file_extension(
1✔
406
            GameType::Fallout3,
1✔
407
            extension
1✔
408
        ));
1✔
409
        assert!(!is_unghosted_plugin_file_extension(
1✔
410
            GameType::FalloutNV,
1✔
411
            extension
1✔
412
        ));
1✔
413
        assert!(!is_unghosted_plugin_file_extension(
1✔
414
            GameType::Fallout4,
1✔
415
            extension
1✔
416
        ));
1✔
417
        assert!(!is_unghosted_plugin_file_extension(
1✔
418
            GameType::Fallout4VR,
1✔
419
            extension
1✔
420
        ));
1✔
421
    }
1✔
422

423
    #[test]
424
    fn is_unghosted_plugin_file_extension_should_be_false_for_ghost_for_all_game_types() {
1✔
425
        let extension = OsStr::new("Ghost");
1✔
426

1✔
427
        assert!(!is_unghosted_plugin_file_extension(
1✔
428
            GameType::OpenMW,
1✔
429
            extension
1✔
430
        ));
1✔
431
        assert!(!is_unghosted_plugin_file_extension(
1✔
432
            GameType::Morrowind,
1✔
433
            extension
1✔
434
        ));
1✔
435
        assert!(!is_unghosted_plugin_file_extension(
1✔
436
            GameType::Oblivion,
1✔
437
            extension
1✔
438
        ));
1✔
439
        assert!(!is_unghosted_plugin_file_extension(
1✔
440
            GameType::Skyrim,
1✔
441
            extension
1✔
442
        ));
1✔
443
        assert!(!is_unghosted_plugin_file_extension(
1✔
444
            GameType::SkyrimSE,
1✔
445
            extension
1✔
446
        ));
1✔
447
        assert!(!is_unghosted_plugin_file_extension(
1✔
448
            GameType::SkyrimVR,
1✔
449
            extension
1✔
450
        ));
1✔
451
        assert!(!is_unghosted_plugin_file_extension(
1✔
452
            GameType::Fallout3,
1✔
453
            extension
1✔
454
        ));
1✔
455
        assert!(!is_unghosted_plugin_file_extension(
1✔
456
            GameType::FalloutNV,
1✔
457
            extension
1✔
458
        ));
1✔
459
        assert!(!is_unghosted_plugin_file_extension(
1✔
460
            GameType::Fallout4,
1✔
461
            extension
1✔
462
        ));
1✔
463
        assert!(!is_unghosted_plugin_file_extension(
1✔
464
            GameType::Fallout4VR,
1✔
465
            extension
1✔
466
        ));
1✔
467
    }
1✔
468

469
    #[test]
470
    fn is_unghosted_plugin_file_extension_should_be_false_for_non_esp_esm_esl_for_all_game_types() {
1✔
471
        let extension = OsStr::new("txt");
1✔
472

1✔
473
        assert!(!is_unghosted_plugin_file_extension(
1✔
474
            GameType::OpenMW,
1✔
475
            extension
1✔
476
        ));
1✔
477
        assert!(!is_unghosted_plugin_file_extension(
1✔
478
            GameType::Morrowind,
1✔
479
            extension
1✔
480
        ));
1✔
481
        assert!(!is_unghosted_plugin_file_extension(
1✔
482
            GameType::Oblivion,
1✔
483
            extension
1✔
484
        ));
1✔
485
        assert!(!is_unghosted_plugin_file_extension(
1✔
486
            GameType::Skyrim,
1✔
487
            extension
1✔
488
        ));
1✔
489
        assert!(!is_unghosted_plugin_file_extension(
1✔
490
            GameType::SkyrimSE,
1✔
491
            extension
1✔
492
        ));
1✔
493
        assert!(!is_unghosted_plugin_file_extension(
1✔
494
            GameType::SkyrimVR,
1✔
495
            extension
1✔
496
        ));
1✔
497
        assert!(!is_unghosted_plugin_file_extension(
1✔
498
            GameType::Fallout3,
1✔
499
            extension
1✔
500
        ));
1✔
501
        assert!(!is_unghosted_plugin_file_extension(
1✔
502
            GameType::FalloutNV,
1✔
503
            extension
1✔
504
        ));
1✔
505
        assert!(!is_unghosted_plugin_file_extension(
1✔
506
            GameType::Fallout4,
1✔
507
            extension
1✔
508
        ));
1✔
509
        assert!(!is_unghosted_plugin_file_extension(
1✔
510
            GameType::Fallout4VR,
1✔
511
            extension
1✔
512
        ));
1✔
513
    }
1✔
514

515
    #[test]
516
    fn has_unghosted_plugin_file_extension_should_return_false_if_the_path_has_no_extension() {
1✔
517
        assert!(!has_unghosted_plugin_file_extension(
1✔
518
            GameType::Skyrim,
1✔
519
            Path::new("file")
1✔
520
        ));
1✔
521
    }
1✔
522

523
    #[test]
524
    fn has_unghosted_plugin_file_extension_should_return_false_if_the_path_has_a_non_plugin_extension(
1✔
525
    ) {
1✔
526
        assert!(!has_unghosted_plugin_file_extension(
1✔
527
            GameType::Skyrim,
1✔
528
            Path::new("plugin.bsa")
1✔
529
        ));
1✔
530
    }
1✔
531

532
    #[test]
533
    fn has_unghosted_plugin_file_extension_should_return_false_if_the_path_has_a_ghosted_plugin_extension(
1✔
534
    ) {
1✔
535
        assert!(!has_unghosted_plugin_file_extension(
1✔
536
            GameType::Skyrim,
1✔
537
            Path::new("plugin.esp.ghost")
1✔
538
        ));
1✔
539
    }
1✔
540

541
    #[test]
542
    fn has_unghosted_plugin_file_extension_should_return_true_if_the_path_has_an_unghosted_plugin_extension(
1✔
543
    ) {
1✔
544
        assert!(has_unghosted_plugin_file_extension(
1✔
545
            GameType::Skyrim,
1✔
546
            Path::new("plugin.esp")
1✔
547
        ));
1✔
548
    }
1✔
549

550
    #[test]
551
    fn has_plugin_file_extension_should_return_true_if_the_path_has_an_unghosted_plugin_extension()
1✔
552
    {
1✔
553
        assert!(has_plugin_file_extension(
1✔
554
            GameType::Skyrim,
1✔
555
            Path::new("plugin.esp")
1✔
556
        ));
1✔
557
    }
1✔
558

559
    #[test]
560
    fn has_plugin_file_extension_should_return_true_if_the_path_has_a_ghosted_plugin_extension() {
1✔
561
        assert!(has_plugin_file_extension(
1✔
562
            GameType::Skyrim,
1✔
563
            Path::new("plugin.esp.Ghost")
1✔
564
        ));
1✔
565
    }
1✔
566

567
    #[test]
568
    fn has_plugin_file_extension_should_return_false_if_the_path_has_a_ghosted_plugin_extension_for_openmw(
1✔
569
    ) {
1✔
570
        assert!(!has_plugin_file_extension(
1✔
571
            GameType::OpenMW,
1✔
572
            Path::new("plugin.esp.Ghost")
1✔
573
        ));
1✔
574
    }
1✔
575

576
    #[test]
577
    fn has_plugin_file_extension_should_return_false_if_the_path_has_a_non_plugin_extension() {
1✔
578
        assert!(!has_plugin_file_extension(
1✔
579
            GameType::Skyrim,
1✔
580
            Path::new("plugin.bsa")
1✔
581
        ));
1✔
582
    }
1✔
583

584
    #[test]
585
    fn has_plugin_file_extension_should_return_false_if_the_path_has_a_ghosted_non_plugin_extension(
1✔
586
    ) {
1✔
587
        assert!(!has_plugin_file_extension(
1✔
588
            GameType::Skyrim,
1✔
589
            Path::new("plugin.bsa.Ghost")
1✔
590
        ));
1✔
591
    }
1✔
592

593
    #[test]
594
    fn has_plugin_file_extension_should_return_false_if_the_path_has_only_ghost_extension() {
1✔
595
        assert!(!has_plugin_file_extension(
1✔
596
            GameType::Skyrim,
1✔
597
            Path::new("plugin.Ghost")
1✔
598
        ));
1✔
599
    }
1✔
600

601
    #[test]
602
    fn has_plugin_file_extension_should_return_false_if_the_path_has_no_extension() {
1✔
603
        assert!(!has_plugin_file_extension(
1✔
604
            GameType::Skyrim,
1✔
605
            Path::new("plugin")
1✔
606
        ));
1✔
607
    }
1✔
608

609
    #[test]
610
    fn add_ghost_extension_should_add_dot_ghost_to_an_existing_extension() {
1✔
611
        let path = add_ghost_extension(Path::new("plugin.esp"));
1✔
612
        assert_eq!(PathBuf::from("plugin.esp.ghost"), path);
1✔
613
    }
1✔
614

615
    #[test]
616
    fn add_ghost_extension_should_add_dot_ghost_to_an_a_path_with_no_extension() {
1✔
617
        let path = add_ghost_extension(Path::new("plugin"));
1✔
618
        assert_eq!(PathBuf::from("plugin.ghost"), path);
1✔
619
    }
1✔
620

621
    #[test]
622
    fn normalise_file_name_should_remove_ghost_extension_from_a_plugin_filename() {
1✔
623
        assert_eq!(
1✔
624
            "plugin.esp",
1✔
625
            normalise_file_name(GameType::Oblivion, OsStr::new("plugin.esp.ghost"))
1✔
626
        );
1✔
627
    }
1✔
628

629
    #[test]
630
    fn normalise_file_name_should_not_remove_ghost_extension_from_a_non_plugin_filename() {
1✔
631
        assert_eq!(
1✔
632
            "plugin.ghost",
1✔
633
            normalise_file_name(GameType::Oblivion, OsStr::new("plugin.ghost"))
1✔
634
        );
1✔
635
    }
1✔
636

637
    #[test]
638
    fn normalise_file_name_should_return_a_non_ghost_extension_filename_unchanged() {
1✔
639
        assert_eq!(
1✔
640
            "plugin.esp",
1✔
641
            normalise_file_name(GameType::Oblivion, OsStr::new("plugin.esp"))
1✔
642
        );
1✔
643
    }
1✔
644

645
    #[test]
646
    fn normalise_file_name_should_return_the_path_unchanged_for_openmw() {
1✔
647
        assert_eq!(
1✔
648
            "plugin.esp.ghost",
1✔
649
            normalise_file_name(GameType::OpenMW, OsStr::new("plugin.esp.ghost"))
1✔
650
        );
1✔
651
    }
1✔
652

653
    #[test]
654
    fn resolve_path_should_return_the_data_path_prefixed_path_if_it_exists() {
1✔
655
        let data_path = PathBuf::from(".");
1✔
656
        let state = State::new(GameType::Skyrim, data_path.clone());
1✔
657
        let input_path = Path::new("README.md");
1✔
658
        let resolved_path = resolve_path(&state, input_path);
1✔
659

1✔
660
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
661
    }
1✔
662

663
    #[test]
664
    fn resolve_path_should_return_the_data_path_prefixed_path_if_it_does_not_exist_and_is_not_an_unghosted_plugin_filename(
1✔
665
    ) {
1✔
666
        let data_path = PathBuf::from(".");
1✔
667
        let state = State::new(GameType::Skyrim, data_path.clone());
1✔
668
        let input_path = Path::new("plugin.esp.ghost");
1✔
669
        let resolved_path = resolve_path(&state, input_path);
1✔
670

1✔
671
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
672

673
        let input_path = Path::new("file.txt");
1✔
674
        let resolved_path = resolve_path(&state, input_path);
1✔
675

1✔
676
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
677
    }
1✔
678

679
    #[test]
680
    fn resolve_path_should_return_the_given_data_relative_path_plus_a_ghost_extension_if_the_plugin_path_does_not_exist(
1✔
681
    ) {
1✔
682
        let data_path = PathBuf::from(".");
1✔
683
        let state = State::new(GameType::Skyrim, data_path.clone());
1✔
684
        let input_path = Path::new("plugin.esp");
1✔
685
        let resolved_path = resolve_path(&state, input_path);
1✔
686

1✔
687
        assert_eq!(
1✔
688
            data_path.join(input_path.with_extension("esp.ghost")),
1✔
689
            resolved_path
1✔
690
        );
1✔
691
    }
1✔
692

693
    #[test]
694
    fn resolve_path_should_not_add_ghost_extension_for_openmw() {
1✔
695
        let data_path = PathBuf::from(".");
1✔
696
        let state = State::new(GameType::OpenMW, data_path.clone());
1✔
697
        let input_path = Path::new("plugin.esp");
1✔
698
        let resolved_path = resolve_path(&state, input_path);
1✔
699

1✔
700
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
701
    }
1✔
702

703
    #[test]
704
    fn resolve_path_should_check_external_data_paths_in_order_before_data_path() {
1✔
705
        use std::fs::copy;
706

707
        let tmp_dir = tempfile::tempdir().unwrap();
1✔
708
        let external_data_path_1 = tmp_dir.path().join("Data1");
1✔
709
        let external_data_path_2 = tmp_dir.path().join("Data2");
1✔
710
        let data_path = tmp_dir.path().join("Data3");
1✔
711

1✔
712
        create_dir_all(&external_data_path_1).unwrap();
1✔
713
        create_dir_all(&external_data_path_2).unwrap();
1✔
714
        create_dir_all(&data_path).unwrap();
1✔
715
        copy(
1✔
716
            Path::new("Cargo.toml"),
1✔
717
            external_data_path_1.join("Cargo.toml"),
1✔
718
        )
1✔
719
        .unwrap();
1✔
720
        copy(
1✔
721
            Path::new("Cargo.toml"),
1✔
722
            external_data_path_2.join("Cargo.toml"),
1✔
723
        )
1✔
724
        .unwrap();
1✔
725
        copy(Path::new("Cargo.toml"), data_path.join("Cargo.toml")).unwrap();
1✔
726

1✔
727
        let mut state = State::new(GameType::Skyrim, data_path);
1✔
728
        state.set_additional_data_paths(vec![
1✔
729
            external_data_path_1.clone(),
1✔
730
            external_data_path_2.clone(),
1✔
731
        ]);
1✔
732

1✔
733
        let input_path = Path::new("Cargo.toml");
1✔
734
        let resolved_path = resolve_path(&state, input_path);
1✔
735

1✔
736
        assert_eq!(external_data_path_1.join(input_path), resolved_path);
1✔
737
    }
1✔
738

739
    #[test]
740
    fn resolve_path_should_check_external_data_paths_in_reverse_order_before_data_path_for_openmw()
1✔
741
    {
1✔
742
        use std::fs::copy;
743

744
        let tmp_dir = tempfile::tempdir().unwrap();
1✔
745
        let external_data_path_1 = tmp_dir.path().join("Data1");
1✔
746
        let external_data_path_2 = tmp_dir.path().join("Data2");
1✔
747
        let data_path = tmp_dir.path().join("Data3");
1✔
748

1✔
749
        create_dir_all(&external_data_path_1).unwrap();
1✔
750
        create_dir_all(&external_data_path_2).unwrap();
1✔
751
        create_dir_all(&data_path).unwrap();
1✔
752
        copy(
1✔
753
            Path::new("Cargo.toml"),
1✔
754
            external_data_path_1.join("Cargo.toml"),
1✔
755
        )
1✔
756
        .unwrap();
1✔
757
        copy(
1✔
758
            Path::new("Cargo.toml"),
1✔
759
            external_data_path_2.join("Cargo.toml"),
1✔
760
        )
1✔
761
        .unwrap();
1✔
762
        copy(Path::new("Cargo.toml"), data_path.join("Cargo.toml")).unwrap();
1✔
763

1✔
764
        let mut state = State::new(GameType::OpenMW, data_path);
1✔
765
        state.set_additional_data_paths(vec![
1✔
766
            external_data_path_1.clone(),
1✔
767
            external_data_path_2.clone(),
1✔
768
        ]);
1✔
769

1✔
770
        let input_path = Path::new("Cargo.toml");
1✔
771
        let resolved_path = resolve_path(&state, input_path);
1✔
772

1✔
773
        assert_eq!(external_data_path_2.join(input_path), resolved_path);
1✔
774
    }
1✔
775
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc