Skip to main content

oxiphysics_io/database_io/
functions.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5#[cfg(test)]
6mod tests {
7
8    use crate::database_io::CacheEntry;
9    use crate::database_io::DataCatalog;
10    use crate::database_io::DatabaseQuery;
11    use crate::database_io::DatabaseSerializer;
12    use crate::database_io::DbRow;
13    use crate::database_io::DbValue;
14    use crate::database_io::ExportFilter;
15    use crate::database_io::ExportFormat;
16    use crate::database_io::ExportPipeline;
17    use crate::database_io::MaterialDatabase;
18    use crate::database_io::ResultCache;
19    use crate::database_io::SimulationDatabase;
20    use crate::database_io::SimulationMetadata;
21    use crate::database_io::SimulationRecord;
22    use crate::database_io::SimulationRecordDatabase;
23    use crate::database_io::SnapshotCatalog;
24    use crate::database_io::SnapshotEntry;
25    use crate::database_io::TimeSeriesStore;
26
27    #[test]
28    fn test_dbvalue_as_f64_float() {
29        let v = DbValue::Float(3.125);
30        assert!((v.as_f64().unwrap() - 3.125).abs() < 1e-10);
31    }
32    #[test]
33    fn test_dbvalue_as_f64_int() {
34        let v = DbValue::Int(7);
35        assert!((v.as_f64().unwrap() - 7.0).abs() < 1e-10);
36    }
37    #[test]
38    fn test_dbvalue_as_f64_text_is_none() {
39        let v = DbValue::Text("hello".into());
40        assert!(v.as_f64().is_none());
41    }
42    #[test]
43    fn test_dbvalue_as_str() {
44        let v = DbValue::Text("world".into());
45        assert_eq!(v.as_str(), Some("world"));
46    }
47    #[test]
48    fn test_dbvalue_from_conversions() {
49        let _: DbValue = 3.125f64.into();
50        let _: DbValue = 42i64.into();
51        let _: DbValue = "hello".into();
52        let _: DbValue = true.into();
53    }
54    #[test]
55    fn test_dbrow_set_get() {
56        let mut row = DbRow::new();
57        row.set("x", 1.5f64);
58        assert_eq!(row.get("x"), Some(&DbValue::Float(1.5)));
59    }
60    #[test]
61    fn test_dbrow_missing_key() {
62        let row = DbRow::new();
63        assert!(row.get("missing").is_none());
64    }
65    #[test]
66    fn test_simdb_insert_count() {
67        let mut db = SimulationDatabase::new("test");
68        let mut row = DbRow::new();
69        row.set("step", 1i64);
70        db.insert(row);
71        assert_eq!(db.row_count(), 1);
72    }
73    #[test]
74    fn test_simdb_query_eq() {
75        let mut db = SimulationDatabase::new("test");
76        for i in 0i64..5 {
77            let mut row = DbRow::new();
78            row.set("id", i);
79            db.insert(row);
80        }
81        let results = db.query_eq("id", &DbValue::Int(3));
82        assert_eq!(results.len(), 1);
83    }
84    #[test]
85    fn test_simdb_query_range() {
86        let mut db = SimulationDatabase::new("test");
87        for i in 0..10 {
88            let mut row = DbRow::new();
89            row.set("t", i as f64);
90            db.insert(row);
91        }
92        let results = db.query_range("t", 3.0, 6.0);
93        assert_eq!(results.len(), 4);
94    }
95    #[test]
96    fn test_simdb_delete_eq() {
97        let mut db = SimulationDatabase::new("test");
98        for i in 0i64..5 {
99            let mut row = DbRow::new();
100            row.set("id", i);
101            db.insert(row);
102        }
103        let deleted = db.delete_eq("id", &DbValue::Int(2));
104        assert_eq!(deleted, 1);
105        assert_eq!(db.row_count(), 4);
106    }
107    #[test]
108    fn test_simdb_clear() {
109        let mut db = SimulationDatabase::new("test");
110        for _ in 0..3 {
111            db.insert(DbRow::new());
112        }
113        db.clear();
114        assert_eq!(db.row_count(), 0);
115    }
116    #[test]
117    fn test_simdb_column_mean() {
118        let mut db = SimulationDatabase::new("test");
119        for i in 0..4 {
120            let mut row = DbRow::new();
121            row.set("v", i as f64);
122            db.insert(row);
123        }
124        let mean = db.column_mean("v").unwrap();
125        assert!((mean - 1.5).abs() < 1e-10, "mean = {mean}");
126    }
127    #[test]
128    fn test_simdb_column_mean_empty() {
129        let db = SimulationDatabase::new("test");
130        assert!(db.column_mean("v").is_none());
131    }
132    #[test]
133    fn test_simdb_project() {
134        let mut db = SimulationDatabase::new("test");
135        let mut row = DbRow::new();
136        row.set("x", 1.0f64);
137        row.set("y", 2.0f64);
138        row.set("z", 3.0f64);
139        db.insert(row);
140        let proj = db.project(&["x", "z"]);
141        assert_eq!(proj.len(), 1);
142        assert!(proj[0].contains_key("x"));
143        assert!(!proj[0].contains_key("y"));
144    }
145    #[test]
146    fn test_ts_append_len() {
147        let mut ts = TimeSeriesStore::new("pressure");
148        ts.append(0.0, 100.0);
149        ts.append(0.1, 101.0);
150        assert_eq!(ts.len(), 2);
151    }
152    #[test]
153    fn test_ts_range_query() {
154        let mut ts = TimeSeriesStore::new("temp");
155        for i in 0..10 {
156            ts.append(i as f64 * 0.1, i as f64);
157        }
158        let results = ts.range_query(0.2, 0.5);
159        assert_eq!(results.len(), 4);
160    }
161    #[test]
162    fn test_ts_decimate() {
163        let mut ts = TimeSeriesStore::new("v");
164        for i in 0..10 {
165            ts.append(i as f64, i as f64);
166        }
167        let dec = ts.decimate(2);
168        assert_eq!(dec.len(), 5);
169    }
170    #[test]
171    fn test_ts_decimate_zero() {
172        let mut ts = TimeSeriesStore::new("v");
173        ts.append(0.0, 1.0);
174        let dec = ts.decimate(0);
175        assert!(dec.is_empty());
176    }
177    #[test]
178    fn test_ts_mean_in_range() {
179        let mut ts = TimeSeriesStore::new("x");
180        ts.append(0.0, 0.0);
181        ts.append(1.0, 2.0);
182        ts.append(2.0, 4.0);
183        let mean = ts.mean_in_range(0.0, 2.0).unwrap();
184        assert!((mean - 2.0).abs() < 1e-10);
185    }
186    #[test]
187    fn test_ts_max_min() {
188        let mut ts = TimeSeriesStore::new("y");
189        ts.append(0.0, 3.0);
190        ts.append(1.0, 7.0);
191        ts.append(2.0, 1.0);
192        assert!((ts.max_value().unwrap() - 7.0).abs() < 1e-10);
193        assert!((ts.min_value().unwrap() - 1.0).abs() < 1e-10);
194    }
195    #[test]
196    fn test_ts_interpolate_midpoint() {
197        let mut ts = TimeSeriesStore::new("f");
198        ts.append(0.0, 0.0);
199        ts.append(1.0, 10.0);
200        let v = ts.interpolate(0.5).unwrap();
201        assert!((v - 5.0).abs() < 1e-10);
202    }
203    #[test]
204    fn test_ts_interpolate_empty() {
205        let ts = TimeSeriesStore::new("f");
206        assert!(ts.interpolate(0.5).is_none());
207    }
208    #[test]
209    fn test_ts_to_csv() {
210        let mut ts = TimeSeriesStore::new("p");
211        ts.append(0.0, 1.0);
212        let csv = ts.to_csv();
213        assert!(csv.starts_with("time,value\n"));
214        assert!(csv.contains("0"));
215    }
216    #[test]
217    fn test_matdb_defaults_non_empty() {
218        let db = MaterialDatabase::with_defaults();
219        assert!(!db.is_empty());
220    }
221    #[test]
222    fn test_matdb_lookup_steel() {
223        let db = MaterialDatabase::with_defaults();
224        let rec = db.lookup("steel_1020").unwrap();
225        assert!((rec.density - 7850.0).abs() < 1.0);
226    }
227    #[test]
228    fn test_matdb_lookup_missing() {
229        let db = MaterialDatabase::with_defaults();
230        assert!(db.lookup("unobtanium").is_none());
231    }
232    #[test]
233    fn test_matdb_fuzzy_search() {
234        let db = MaterialDatabase::with_defaults();
235        let results = db.fuzzy_search("metal");
236        assert!(!results.is_empty());
237    }
238    #[test]
239    fn test_matdb_fuzzy_search_no_match() {
240        let db = MaterialDatabase::with_defaults();
241        let results = db.fuzzy_search("unobtanium_xyz");
242        assert!(results.is_empty());
243    }
244    #[test]
245    fn test_matdb_interpolate() {
246        let db = MaterialDatabase::with_defaults();
247        let blended = db.interpolate("steel_1020", "aluminium_6061", 0.5).unwrap();
248        assert!(blended.density > 2700.0 && blended.density < 7850.0);
249    }
250    #[test]
251    fn test_matdb_interpolate_t0() {
252        let db = MaterialDatabase::with_defaults();
253        let rec = db.interpolate("steel_1020", "copper", 0.0).unwrap();
254        assert!((rec.density - 7850.0).abs() < 1.0);
255    }
256    #[test]
257    fn test_matdb_names() {
258        let db = MaterialDatabase::with_defaults();
259        let names = db.names();
260        assert!(names.contains(&"steel_1020"));
261    }
262    #[test]
263    fn test_cache_put_get() {
264        let mut cache = ResultCache::new(4);
265        cache.put(CacheEntry::new("k1", vec![1.0, 2.0], 0.0, 0));
266        let entry = cache.get("k1").unwrap();
267        assert_eq!(entry.data, vec![1.0, 2.0]);
268    }
269    #[test]
270    fn test_cache_eviction() {
271        let mut cache = ResultCache::new(2);
272        cache.put(CacheEntry::new("k1", vec![], 0.0, 0));
273        cache.put(CacheEntry::new("k2", vec![], 0.0, 0));
274        cache.put(CacheEntry::new("k3", vec![], 0.0, 0));
275        assert!(cache.get("k1").is_none());
276        assert!(cache.get("k2").is_some() || cache.get("k3").is_some());
277    }
278    #[test]
279    fn test_cache_invalidate_all() {
280        let mut cache = ResultCache::new(4);
281        cache.put(CacheEntry::new("k1", vec![], 0.0, 0));
282        cache.invalidate_all();
283        assert!(cache.get("k1").is_none());
284    }
285    #[test]
286    fn test_cache_remove() {
287        let mut cache = ResultCache::new(4);
288        cache.put(CacheEntry::new("k1", vec![], 0.0, 0));
289        cache.remove("k1");
290        assert!(cache.get("k1").is_none());
291    }
292    #[test]
293    fn test_cache_evict_stale() {
294        let mut cache = ResultCache::new(10);
295        cache.put(CacheEntry::new("old", vec![], 0.0, 0));
296        cache.invalidate_all();
297        cache.put(CacheEntry::new("fresh", vec![], 1.0, 1));
298        cache.evict_stale();
299        assert_eq!(cache.len(), 1);
300    }
301    #[test]
302    fn test_cache_lru_order() {
303        let mut cache = ResultCache::new(3);
304        cache.put(CacheEntry::new("a", vec![], 0.0, 0));
305        cache.put(CacheEntry::new("b", vec![], 0.0, 0));
306        cache.put(CacheEntry::new("c", vec![], 0.0, 0));
307        let _ = cache.get("a");
308        cache.put(CacheEntry::new("d", vec![], 0.0, 0));
309        assert!(cache.get("a").is_some());
310        assert!(cache.get("b").is_none());
311    }
312    #[test]
313    fn test_catalog_register_lookup() {
314        let mut cat = DataCatalog::new();
315        let meta = SimulationMetadata::new("sim001", "Test run", 0.0);
316        cat.register(meta);
317        assert!(cat.lookup("sim001").is_some());
318    }
319    #[test]
320    fn test_catalog_remove() {
321        let mut cat = DataCatalog::new();
322        cat.register(SimulationMetadata::new("s1", "desc", 0.0));
323        let removed = cat.remove("s1");
324        assert!(removed);
325        assert!(cat.lookup("s1").is_none());
326    }
327    #[test]
328    fn test_catalog_search_description() {
329        let mut cat = DataCatalog::new();
330        cat.register(SimulationMetadata::new("s1", "turbulence simulation", 0.0));
331        cat.register(SimulationMetadata::new("s2", "heat transfer", 0.0));
332        let results = cat.search_description("turbulence");
333        assert_eq!(results.len(), 1);
334    }
335    #[test]
336    fn test_catalog_metadata_params() {
337        let mut cat = DataCatalog::new();
338        cat.register(SimulationMetadata::new("s1", "run", 0.0));
339        let meta = cat.lookup_mut("s1").unwrap();
340        meta.set_param("dt", "0.01");
341        meta.add_artifact("/tmp/result.vtk");
342        let meta2 = cat.lookup("s1").unwrap();
343        assert_eq!(meta2.parameters.get("dt"), Some(&"0.01".to_string()));
344        assert_eq!(meta2.artifacts.len(), 1);
345    }
346    #[test]
347    fn test_catalog_all_ids() {
348        let mut cat = DataCatalog::new();
349        cat.register(SimulationMetadata::new("a", "", 0.0));
350        cat.register(SimulationMetadata::new("b", "", 0.0));
351        let ids = cat.all_ids();
352        assert_eq!(ids.len(), 2);
353    }
354    fn make_test_db() -> SimulationDatabase {
355        let mut db = SimulationDatabase::new("runs");
356        for i in 0..3 {
357            let mut row = DbRow::new();
358            row.set("step", i as i64);
359            row.set("energy", (i as f64) * 10.0);
360            row.set("label", format!("step_{i}").as_str());
361            db.insert(row);
362        }
363        db
364    }
365    #[test]
366    fn test_export_csv_basic() {
367        let db = make_test_db();
368        let pipe = ExportPipeline::new(ExportFormat::Csv);
369        let out = pipe.export(&db);
370        assert!(out.contains("step"));
371        assert!(out.contains("energy"));
372    }
373    #[test]
374    fn test_export_json_basic() {
375        let db = make_test_db();
376        let pipe = ExportPipeline::new(ExportFormat::Json);
377        let out = pipe.export(&db);
378        assert!(out.starts_with('['));
379        assert!(out.ends_with(']'));
380    }
381    #[test]
382    fn test_export_hdf5text_basic() {
383        let db = make_test_db();
384        let pipe = ExportPipeline::new(ExportFormat::Hdf5Text);
385        let out = pipe.export(&db);
386        assert!(out.contains("# HDF5-like"));
387        assert!(out.contains("runs"));
388    }
389    #[test]
390    fn test_export_with_range_filter() {
391        let db = make_test_db();
392        let mut filter = ExportFilter::new();
393        filter.min_value = Some(("energy".into(), 5.0));
394        let pipe = ExportPipeline::new(ExportFormat::Csv).with_filter(filter);
395        let out = pipe.export(&db);
396        let data_lines = out.lines().skip(1).count();
397        assert_eq!(data_lines, 2);
398    }
399    #[test]
400    fn test_export_with_column_projection() {
401        let db = make_test_db();
402        let mut filter = ExportFilter::new();
403        filter.columns = vec!["step".into()];
404        let pipe = ExportPipeline::new(ExportFormat::Csv).with_filter(filter);
405        let out = pipe.export(&db);
406        assert!(out.contains("step"));
407        assert!(!out.contains("energy"));
408    }
409    #[test]
410    fn test_export_empty_db() {
411        let db = SimulationDatabase::new("empty");
412        let pipe = ExportPipeline::new(ExportFormat::Csv);
413        let out = pipe.export(&db);
414        assert!(out.is_empty() || !out.contains('\n').eq(&false));
415    }
416    #[test]
417    fn test_export_filter_max_value() {
418        let db = make_test_db();
419        let mut filter = ExportFilter::new();
420        filter.max_value = Some(("energy".into(), 5.0));
421        let pipe = ExportPipeline::new(ExportFormat::Json).with_filter(filter);
422        let out = pipe.export(&db);
423        let obj_count = out.matches('{').count();
424        assert_eq!(obj_count, 1);
425    }
426    #[test]
427    fn test_sim_record_new() {
428        let rec = SimulationRecord::new("run_001", 1234.0_f64);
429        assert_eq!(rec.name, "run_001");
430        assert!((rec.timestamp - 1234.0_f64).abs() < 1e-10);
431        assert!(rec.params.is_empty());
432        assert!(rec.output_path.is_none());
433    }
434    #[test]
435    fn test_sim_record_set_get_param() {
436        let mut rec = SimulationRecord::new("r", 0.0_f64);
437        rec.set_param("dt", "0.01");
438        rec.set_param("steps", "1000");
439        assert_eq!(rec.get_param("dt"), Some("0.01"));
440        assert_eq!(rec.get_param("steps"), Some("1000"));
441        assert!(rec.get_param("missing").is_none());
442    }
443    #[test]
444    fn test_sim_record_set_output() {
445        let mut rec = SimulationRecord::new("r", 0.0_f64);
446        rec.set_output("/tmp/result.vtk");
447        assert_eq!(rec.output_path, Some("/tmp/result.vtk".to_string()));
448    }
449    #[test]
450    fn test_query_time_range_pass() {
451        let rec = SimulationRecord::new("x", 5.0_f64);
452        let q = DatabaseQuery::new().with_time_range(0.0_f64, 10.0_f64);
453        assert!(q.matches(&rec));
454    }
455    #[test]
456    fn test_query_time_range_fail_before() {
457        let rec = SimulationRecord::new("x", -1.0_f64);
458        let q = DatabaseQuery::new().with_time_range(0.0_f64, 10.0_f64);
459        assert!(!q.matches(&rec));
460    }
461    #[test]
462    fn test_query_time_range_fail_after() {
463        let rec = SimulationRecord::new("x", 100.0_f64);
464        let q = DatabaseQuery::new().with_time_range(0.0_f64, 10.0_f64);
465        assert!(!q.matches(&rec));
466    }
467    #[test]
468    fn test_query_name_prefix_pass() {
469        let rec = SimulationRecord::new("run_001", 0.0_f64);
470        let q = DatabaseQuery::new().with_name_prefix("run_");
471        assert!(q.matches(&rec));
472    }
473    #[test]
474    fn test_query_name_prefix_fail() {
475        let rec = SimulationRecord::new("sim_001", 0.0_f64);
476        let q = DatabaseQuery::new().with_name_prefix("run_");
477        assert!(!q.matches(&rec));
478    }
479    #[test]
480    fn test_query_param_filter_pass() {
481        let mut rec = SimulationRecord::new("r", 0.0_f64);
482        rec.set_param("solver", "cg");
483        let q = DatabaseQuery::new().with_param("solver", "cg");
484        assert!(q.matches(&rec));
485    }
486    #[test]
487    fn test_query_param_filter_fail() {
488        let mut rec = SimulationRecord::new("r", 0.0_f64);
489        rec.set_param("solver", "direct");
490        let q = DatabaseQuery::new().with_param("solver", "cg");
491        assert!(!q.matches(&rec));
492    }
493    #[test]
494    fn test_query_empty_passes_all() {
495        let rec = SimulationRecord::new("anything", 999.0_f64);
496        let q = DatabaseQuery::new();
497        assert!(q.matches(&rec));
498    }
499    #[test]
500    fn test_record_db_insert_get() {
501        let mut db = SimulationRecordDatabase::new();
502        db.insert(SimulationRecord::new("r1", 1.0_f64));
503        assert!(db.get("r1").is_some());
504        assert_eq!(db.count(), 1);
505    }
506    #[test]
507    fn test_record_db_delete() {
508        let mut db = SimulationRecordDatabase::new();
509        db.insert(SimulationRecord::new("r1", 0.0_f64));
510        let removed = db.delete("r1");
511        assert!(removed);
512        assert!(db.get("r1").is_none());
513        assert_eq!(db.count(), 0);
514    }
515    #[test]
516    fn test_record_db_delete_missing() {
517        let mut db = SimulationRecordDatabase::new();
518        assert!(!db.delete("nonexistent"));
519    }
520    #[test]
521    fn test_record_db_update() {
522        let mut db = SimulationRecordDatabase::new();
523        db.insert(SimulationRecord::new("r1", 0.0_f64));
524        db.get_mut("r1").unwrap().set_param("dt", "0.01");
525        assert_eq!(db.get("r1").unwrap().get_param("dt"), Some("0.01"));
526    }
527    #[test]
528    fn test_record_db_query() {
529        let mut db = SimulationRecordDatabase::new();
530        for i in 0..5 {
531            let mut rec = SimulationRecord::new(format!("run_{i}"), i as f64);
532            rec.set_param("type", "fluid");
533            db.insert(rec);
534        }
535        let q = DatabaseQuery::new()
536            .with_time_range(1.0_f64, 3.0_f64)
537            .with_param("type", "fluid");
538        let results = db.query(&q);
539        assert_eq!(results.len(), 3);
540    }
541    #[test]
542    fn test_record_db_names() {
543        let mut db = SimulationRecordDatabase::new();
544        db.insert(SimulationRecord::new("a", 0.0_f64));
545        db.insert(SimulationRecord::new("b", 0.0_f64));
546        let names = db.names();
547        assert_eq!(names.len(), 2);
548    }
549    #[test]
550    fn test_record_db_clear() {
551        let mut db = SimulationRecordDatabase::new();
552        db.insert(SimulationRecord::new("x", 0.0_f64));
553        db.clear();
554        assert!(db.is_empty());
555    }
556    #[test]
557    fn test_serializer_round_trip_name_timestamp() {
558        let ser = DatabaseSerializer::new();
559        let rec = SimulationRecord::new("run_test", 42.5_f64);
560        let s = ser.serialize(&rec);
561        let rec2 = ser.deserialize(&s).expect("deserialize failed");
562        assert_eq!(rec2.name, "run_test");
563        assert!((rec2.timestamp - 42.5_f64).abs() < 1e-6_f64);
564    }
565    #[test]
566    fn test_serializer_serialize_contains_name() {
567        let ser = DatabaseSerializer::new();
568        let rec = SimulationRecord::new("my_run", 0.0_f64);
569        let s = ser.serialize(&rec);
570        assert!(s.contains("my_run"));
571        assert!(s.contains("timestamp"));
572    }
573    #[test]
574    fn test_serializer_serialize_all() {
575        let ser = DatabaseSerializer::new();
576        let r1 = SimulationRecord::new("a", 0.0_f64);
577        let r2 = SimulationRecord::new("b", 1.0_f64);
578        let out = ser.serialize_all(&[&r1, &r2]);
579        assert!(out.starts_with('['));
580        assert!(out.ends_with(']'));
581    }
582    #[test]
583    fn test_serializer_output_path() {
584        let ser = DatabaseSerializer::new();
585        let mut rec = SimulationRecord::new("r", 0.0_f64);
586        rec.set_output("/data/result.vtu");
587        let s = ser.serialize(&rec);
588        assert!(s.contains("/data/result.vtu"));
589    }
590    #[test]
591    fn test_snapshot_catalog_register_get() {
592        let mut cat = SnapshotCatalog::new();
593        let entry = SnapshotEntry::new("frame_001", 0.1_f64, "/tmp/f001.vtk");
594        cat.register(entry);
595        assert!(cat.get("frame_001").is_some());
596        assert_eq!(cat.len(), 1);
597    }
598    #[test]
599    fn test_snapshot_catalog_auto_id() {
600        let mut cat = SnapshotCatalog::new();
601        let id = cat.register_auto(0.5_f64, "/tmp/snap.vtk");
602        assert!(id.starts_with("snap_"));
603        assert_eq!(cat.len(), 1);
604    }
605    #[test]
606    fn test_snapshot_catalog_remove() {
607        let mut cat = SnapshotCatalog::new();
608        cat.register(SnapshotEntry::new("s1", 0.0_f64, ""));
609        assert!(cat.remove("s1"));
610        assert!(cat.is_empty());
611        assert!(!cat.remove("s1"));
612    }
613    #[test]
614    fn test_snapshot_catalog_range_query() {
615        let mut cat = SnapshotCatalog::new();
616        for i in 0..10 {
617            cat.register(SnapshotEntry::new(format!("s{i}"), i as f64 * 0.1_f64, ""));
618        }
619        let results = cat.range_query(0.2_f64, 0.5_f64);
620        assert_eq!(results.len(), 4);
621    }
622    #[test]
623    fn test_snapshot_catalog_query_by_tag() {
624        let mut cat = SnapshotCatalog::new();
625        let mut s1 = SnapshotEntry::new("s1", 0.0_f64, "");
626        s1.add_tag("checkpoint");
627        let mut s2 = SnapshotEntry::new("s2", 1.0_f64, "");
628        s2.add_tag("debug");
629        cat.register(s1);
630        cat.register(s2);
631        let cps = cat.query_by_tag("checkpoint");
632        assert_eq!(cps.len(), 1);
633    }
634    #[test]
635    fn test_snapshot_catalog_mark_loaded() {
636        let mut cat = SnapshotCatalog::new();
637        cat.register(SnapshotEntry::new("s1", 0.0_f64, ""));
638        cat.register(SnapshotEntry::new("s2", 5.0_f64, ""));
639        cat.mark_range_loaded(0.0_f64, 3.0_f64);
640        assert!(cat.get("s1").unwrap().loaded);
641        assert!(!cat.get("s2").unwrap().loaded);
642    }
643    #[test]
644    fn test_snapshot_catalog_unloaded_ids() {
645        let mut cat = SnapshotCatalog::new();
646        cat.register(SnapshotEntry::new("s1", 0.0_f64, ""));
647        cat.register(SnapshotEntry::new("s2", 1.0_f64, ""));
648        cat.get_mut("s1").unwrap().mark_loaded();
649        let unloaded = cat.unloaded_ids();
650        assert_eq!(unloaded.len(), 1);
651        assert_eq!(unloaded[0], "s2");
652    }
653    #[test]
654    fn test_snapshot_catalog_total_file_size() {
655        let mut cat = SnapshotCatalog::new();
656        let mut s1 = SnapshotEntry::new("s1", 0.0_f64, "");
657        s1.file_size = 1024;
658        let mut s2 = SnapshotEntry::new("s2", 1.0_f64, "");
659        s2.file_size = 2048;
660        cat.register(s1);
661        cat.register(s2);
662        assert_eq!(cat.total_file_size(), 3072);
663    }
664    #[test]
665    fn test_snapshot_catalog_sorted_by_time() {
666        let mut cat = SnapshotCatalog::new();
667        cat.register(SnapshotEntry::new("c", 3.0_f64, ""));
668        cat.register(SnapshotEntry::new("a", 1.0_f64, ""));
669        cat.register(SnapshotEntry::new("b", 2.0_f64, ""));
670        let sorted = cat.sorted_by_time();
671        assert_eq!(sorted.len(), 3);
672        assert!((sorted[0].sim_time - 1.0_f64).abs() < 1e-10);
673        assert!((sorted[2].sim_time - 3.0_f64).abs() < 1e-10);
674    }
675}