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

loot / loot-condition-interpreter / 13038120828

29 Jan 2025 06:38PM UTC coverage: 89.746% (+0.4%) from 89.302%
13038120828

push

github

Ortham
Update versions and changelog for v5.0.0

4070 of 4535 relevant lines covered (89.75%)

15.52 hits per line

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

98.38
/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 {
142✔
12
    extension.eq_ignore_ascii_case("esp")
142✔
13
        || extension.eq_ignore_ascii_case("esm")
123✔
14
        || (game_type.supports_light_plugins() && extension.eq_ignore_ascii_case("esl"))
78✔
15
        || (game_type == GameType::OpenMW
74✔
16
            && (extension.eq_ignore_ascii_case("omwaddon")
6✔
17
                || extension.eq_ignore_ascii_case("omwgame")))
5✔
18
}
142✔
19

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

27
pub fn has_plugin_file_extension(game_type: GameType, path: &Path) -> bool {
14✔
28
    match path.extension() {
14✔
29
        Some(ext)
3✔
30
            if game_type.allows_ghosted_plugins() && ext.eq_ignore_ascii_case(GHOST_EXTENSION) =>
13✔
31
        {
3✔
32
            path.file_stem()
3✔
33
                .map(|s| has_unghosted_plugin_file_extension(game_type, Path::new(s)))
3✔
34
                .unwrap_or(false)
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: PathBuf) -> PathBuf {
6✔
42
    match path.extension() {
6✔
43
        Some(e) => {
5✔
44
            let mut new_extension = e.to_os_string();
5✔
45
            new_extension.push(GHOST_EXTENSION_WITH_PERIOD);
5✔
46
            path.with_extension(&new_extension)
5✔
47
        }
48
        None => path.with_extension(GHOST_EXTENSION),
1✔
49
    }
50
}
6✔
51

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

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

71
    name
73✔
72
}
78✔
73

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

2✔
82
        if joined_path.exists() {
2✔
83
            return Some(joined_path);
2✔
84
        }
×
85

×
86
        if try_with_ghost_extension {
×
87
            let ghosted_path = add_ghost_extension(joined_path);
×
88

×
89
            if ghosted_path.exists() {
×
90
                return Some(ghosted_path);
×
91
            }
×
92
        }
×
93
    }
94

95
    None
79✔
96
}
81✔
97

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

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

119
    if let Some(path) = result {
81✔
120
        return path;
2✔
121
    }
79✔
122

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

79✔
126
    if !joined_path.exists() && try_with_ghost_extension {
79✔
127
        add_ghost_extension(joined_path)
4✔
128
    } else {
129
        joined_path
75✔
130
    }
131
}
81✔
132

133
#[cfg(test)]
134
mod tests {
135
    use super::*;
136

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

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

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

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

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

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

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

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

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

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

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

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

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

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

375
    #[test]
376
    fn is_unghosted_plugin_file_extension_should_be_false_for_ghost_for_all_game_types() {
1✔
377
        let extension = OsStr::new("Ghost");
1✔
378

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

421
    #[test]
422
    fn is_unghosted_plugin_file_extension_should_be_false_for_non_esp_esm_esl_for_all_game_types() {
1✔
423
        let extension = OsStr::new("txt");
1✔
424

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

467
    #[test]
468
    fn has_unghosted_plugin_file_extension_should_return_false_if_the_path_has_no_extension() {
1✔
469
        assert!(!has_unghosted_plugin_file_extension(
1✔
470
            GameType::Skyrim,
1✔
471
            Path::new("file")
1✔
472
        ));
1✔
473
    }
1✔
474

475
    #[test]
476
    fn has_unghosted_plugin_file_extension_should_return_false_if_the_path_has_a_non_plugin_extension(
1✔
477
    ) {
1✔
478
        assert!(!has_unghosted_plugin_file_extension(
1✔
479
            GameType::Skyrim,
1✔
480
            Path::new("plugin.bsa")
1✔
481
        ));
1✔
482
    }
1✔
483

484
    #[test]
485
    fn has_unghosted_plugin_file_extension_should_return_false_if_the_path_has_a_ghosted_plugin_extension(
1✔
486
    ) {
1✔
487
        assert!(!has_unghosted_plugin_file_extension(
1✔
488
            GameType::Skyrim,
1✔
489
            Path::new("plugin.esp.ghost")
1✔
490
        ));
1✔
491
    }
1✔
492

493
    #[test]
494
    fn has_unghosted_plugin_file_extension_should_return_true_if_the_path_has_an_unghosted_plugin_extension(
1✔
495
    ) {
1✔
496
        assert!(has_unghosted_plugin_file_extension(
1✔
497
            GameType::Skyrim,
1✔
498
            Path::new("plugin.esp")
1✔
499
        ));
1✔
500
    }
1✔
501

502
    #[test]
503
    fn has_plugin_file_extension_should_return_true_if_the_path_has_an_unghosted_plugin_extension()
1✔
504
    {
1✔
505
        assert!(has_plugin_file_extension(
1✔
506
            GameType::Skyrim,
1✔
507
            Path::new("plugin.esp")
1✔
508
        ));
1✔
509
    }
1✔
510

511
    #[test]
512
    fn has_plugin_file_extension_should_return_true_if_the_path_has_a_ghosted_plugin_extension() {
1✔
513
        assert!(has_plugin_file_extension(
1✔
514
            GameType::Skyrim,
1✔
515
            Path::new("plugin.esp.Ghost")
1✔
516
        ));
1✔
517
    }
1✔
518

519
    #[test]
520
    fn has_plugin_file_extension_should_return_false_if_the_path_has_a_ghosted_plugin_extension_for_openmw(
1✔
521
    ) {
1✔
522
        assert!(!has_plugin_file_extension(
1✔
523
            GameType::OpenMW,
1✔
524
            Path::new("plugin.esp.Ghost")
1✔
525
        ));
1✔
526
    }
1✔
527

528
    #[test]
529
    fn has_plugin_file_extension_should_return_false_if_the_path_has_a_non_plugin_extension() {
1✔
530
        assert!(!has_plugin_file_extension(
1✔
531
            GameType::Skyrim,
1✔
532
            Path::new("plugin.bsa")
1✔
533
        ));
1✔
534
    }
1✔
535

536
    #[test]
537
    fn has_plugin_file_extension_should_return_false_if_the_path_has_a_ghosted_non_plugin_extension(
1✔
538
    ) {
1✔
539
        assert!(!has_plugin_file_extension(
1✔
540
            GameType::Skyrim,
1✔
541
            Path::new("plugin.bsa.Ghost")
1✔
542
        ));
1✔
543
    }
1✔
544

545
    #[test]
546
    fn has_plugin_file_extension_should_return_false_if_the_path_has_only_ghost_extension() {
1✔
547
        assert!(!has_plugin_file_extension(
1✔
548
            GameType::Skyrim,
1✔
549
            Path::new("plugin.Ghost")
1✔
550
        ));
1✔
551
    }
1✔
552

553
    #[test]
554
    fn has_plugin_file_extension_should_return_false_if_the_path_has_no_extension() {
1✔
555
        assert!(!has_plugin_file_extension(
1✔
556
            GameType::Skyrim,
1✔
557
            Path::new("plugin")
1✔
558
        ));
1✔
559
    }
1✔
560

561
    #[test]
562
    fn add_ghost_extension_should_add_dot_ghost_to_an_existing_extension() {
1✔
563
        let path = add_ghost_extension("plugin.esp".into());
1✔
564
        assert_eq!(PathBuf::from("plugin.esp.ghost"), path);
1✔
565
    }
1✔
566

567
    #[test]
568
    fn add_ghost_extension_should_add_dot_ghost_to_an_a_path_with_no_extension() {
1✔
569
        let path = add_ghost_extension("plugin".into());
1✔
570
        assert_eq!(PathBuf::from("plugin.ghost"), path);
1✔
571
    }
1✔
572

573
    #[test]
574
    fn normalise_file_name_should_remove_ghost_extension_from_a_plugin_filename() {
1✔
575
        assert_eq!(
1✔
576
            "plugin.esp",
1✔
577
            normalise_file_name(GameType::Oblivion, OsStr::new("plugin.esp.ghost"))
1✔
578
        );
1✔
579
    }
1✔
580

581
    #[test]
582
    fn normalise_file_name_should_not_remove_ghost_extension_from_a_non_plugin_filename() {
1✔
583
        assert_eq!(
1✔
584
            "plugin.ghost",
1✔
585
            normalise_file_name(GameType::Oblivion, OsStr::new("plugin.ghost"))
1✔
586
        );
1✔
587
    }
1✔
588

589
    #[test]
590
    fn normalise_file_name_should_return_a_non_ghost_extension_filename_unchanged() {
1✔
591
        assert_eq!(
1✔
592
            "plugin.esp",
1✔
593
            normalise_file_name(GameType::Oblivion, OsStr::new("plugin.esp"))
1✔
594
        );
1✔
595
    }
1✔
596

597
    #[test]
598
    fn normalise_file_name_should_return_the_path_unchanged_for_openmw() {
1✔
599
        assert_eq!(
1✔
600
            "plugin.esp.ghost",
1✔
601
            normalise_file_name(GameType::OpenMW, OsStr::new("plugin.esp.ghost"))
1✔
602
        );
1✔
603
    }
1✔
604

605
    #[test]
606
    fn resolve_path_should_return_the_data_path_prefixed_path_if_it_exists() {
1✔
607
        let data_path = PathBuf::from(".");
1✔
608
        let state = State::new(GameType::Skyrim, data_path.clone());
1✔
609
        let input_path = Path::new("README.md");
1✔
610
        let resolved_path = resolve_path(&state, input_path);
1✔
611

1✔
612
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
613
    }
1✔
614

615
    #[test]
616
    fn resolve_path_should_return_the_data_path_prefixed_path_if_it_does_not_exist_and_is_not_an_unghosted_plugin_filename(
1✔
617
    ) {
1✔
618
        let data_path = PathBuf::from(".");
1✔
619
        let state = State::new(GameType::Skyrim, data_path.clone());
1✔
620
        let input_path = Path::new("plugin.esp.ghost");
1✔
621
        let resolved_path = resolve_path(&state, input_path);
1✔
622

1✔
623
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
624

625
        let input_path = Path::new("file.txt");
1✔
626
        let resolved_path = resolve_path(&state, input_path);
1✔
627

1✔
628
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
629
    }
1✔
630

631
    #[test]
632
    fn resolve_path_should_return_the_given_data_relative_path_plus_a_ghost_extension_if_the_plugin_path_does_not_exist(
1✔
633
    ) {
1✔
634
        let data_path = PathBuf::from(".");
1✔
635
        let state = State::new(GameType::Skyrim, data_path.clone());
1✔
636
        let input_path = Path::new("plugin.esp");
1✔
637
        let resolved_path = resolve_path(&state, input_path);
1✔
638

1✔
639
        assert_eq!(
1✔
640
            data_path.join(input_path.with_extension("esp.ghost")),
1✔
641
            resolved_path
1✔
642
        );
1✔
643
    }
1✔
644

645
    #[test]
646
    fn resolve_path_should_not_add_ghost_extension_for_openmw() {
1✔
647
        let data_path = PathBuf::from(".");
1✔
648
        let state = State::new(GameType::OpenMW, data_path.clone());
1✔
649
        let input_path = Path::new("plugin.esp");
1✔
650
        let resolved_path = resolve_path(&state, input_path);
1✔
651

1✔
652
        assert_eq!(data_path.join(input_path), resolved_path);
1✔
653
    }
1✔
654

655
    #[test]
656
    fn resolve_path_should_check_external_data_paths_in_order_before_data_path() {
1✔
657
        use std::fs::copy;
658
        use std::fs::create_dir;
659

660
        let tmp_dir = tempfile::tempdir().unwrap();
1✔
661
        let external_data_path_1 = tmp_dir.path().join("Data1");
1✔
662
        let external_data_path_2 = tmp_dir.path().join("Data2");
1✔
663
        let data_path = tmp_dir.path().join("Data3");
1✔
664

1✔
665
        create_dir(&external_data_path_1).unwrap();
1✔
666
        create_dir(&external_data_path_2).unwrap();
1✔
667
        create_dir(&data_path).unwrap();
1✔
668
        copy(
1✔
669
            Path::new("Cargo.toml"),
1✔
670
            external_data_path_1.join("Cargo.toml"),
1✔
671
        )
1✔
672
        .unwrap();
1✔
673
        copy(
1✔
674
            Path::new("Cargo.toml"),
1✔
675
            external_data_path_2.join("Cargo.toml"),
1✔
676
        )
1✔
677
        .unwrap();
1✔
678
        copy(Path::new("Cargo.toml"), data_path.join("Cargo.toml")).unwrap();
1✔
679

1✔
680
        let mut state = State::new(GameType::Skyrim, data_path);
1✔
681
        state.set_additional_data_paths(vec![
1✔
682
            external_data_path_1.clone(),
1✔
683
            external_data_path_2.clone(),
1✔
684
        ]);
1✔
685

1✔
686
        let input_path = Path::new("Cargo.toml");
1✔
687
        let resolved_path = resolve_path(&state, input_path);
1✔
688

1✔
689
        assert_eq!(external_data_path_1.join(input_path), resolved_path);
1✔
690
    }
1✔
691

692
    #[test]
693
    fn resolve_path_should_check_external_data_paths_in_reverse_order_before_data_path_for_openmw()
1✔
694
    {
1✔
695
        use std::fs::copy;
696
        use std::fs::create_dir;
697

698
        let tmp_dir = tempfile::tempdir().unwrap();
1✔
699
        let external_data_path_1 = tmp_dir.path().join("Data1");
1✔
700
        let external_data_path_2 = tmp_dir.path().join("Data2");
1✔
701
        let data_path = tmp_dir.path().join("Data3");
1✔
702

1✔
703
        create_dir(&external_data_path_1).unwrap();
1✔
704
        create_dir(&external_data_path_2).unwrap();
1✔
705
        create_dir(&data_path).unwrap();
1✔
706
        copy(
1✔
707
            Path::new("Cargo.toml"),
1✔
708
            external_data_path_1.join("Cargo.toml"),
1✔
709
        )
1✔
710
        .unwrap();
1✔
711
        copy(
1✔
712
            Path::new("Cargo.toml"),
1✔
713
            external_data_path_2.join("Cargo.toml"),
1✔
714
        )
1✔
715
        .unwrap();
1✔
716
        copy(Path::new("Cargo.toml"), data_path.join("Cargo.toml")).unwrap();
1✔
717

1✔
718
        let mut state = State::new(GameType::OpenMW, data_path);
1✔
719
        state.set_additional_data_paths(vec![
1✔
720
            external_data_path_1.clone(),
1✔
721
            external_data_path_2.clone(),
1✔
722
        ]);
1✔
723

1✔
724
        let input_path = Path::new("Cargo.toml");
1✔
725
        let resolved_path = resolve_path(&state, input_path);
1✔
726

1✔
727
        assert_eq!(external_data_path_2.join(input_path), resolved_path);
1✔
728
    }
1✔
729
}
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