#![allow(clippy::panic_in_result_fn)]
#![allow(clippy::print_stdout)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::use_debug)]
use std::fs;
use std::path::Path;
use anyhow::{Context, Result};
use super::{Error as MetadataError, FileHttpMetadata};
#[test]
#[allow(clippy::shadow_reuse)]
#[allow(clippy::shadow_unrelated)]
fn test_simple() -> Result<()> {
let tempd_obj = tempfile::tempdir().context("Could not create a temporary directory")?;
let tempd: &Path = tempd_obj.as_ref();
println!("Using tempd {}", tempd.to_string_lossy());
let path = tempd.join("triv-data.dat");
let path_meta = tempd.join("triv-data.dat.metatriv");
println!("match_meta() should return None if there are no files");
assert!(super::match_meta(&path, &path_meta)?.is_none());
println!("Creating the data file...");
fs::write(&path, "Hello!\n").context("Could not write to the temporary file")?;
println!("match_meta() should return None if there is no meta file");
assert!(super::match_meta(&path, &path_meta)?.is_none());
println!("from_file() should return a valid metadata object");
let meta = FileHttpMetadata::from_file(&path)
.context("Could not obtain metadata from the temporary file")?;
println!("from_file() returned {:?}", meta);
println!("match_meta() should still return None");
assert!(super::match_meta(&path, &path_meta)?.is_none());
println!("Creating the metadata file");
fs::write(
&path_meta,
serde_json::to_string(&meta).context("Could not serialize the metadata")?,
)
.context("Could not write the metadata file")?;
println!("match_meta() should now return something real");
let meta_read =
super::match_meta(&path, &path_meta)?.context("match_meta() should return something")?;
println!("The two metadata objects should be exactly the same");
assert_eq!(meta, meta_read);
println!("Writing modified metadata");
let meta_mod = FileHttpMetadata {
file_size: meta.file_size + 1,
..meta_read
};
fs::write(
&path_meta,
serde_json::to_string(&meta_mod).context("Could not serialize the metadata")?,
)
.context("Could not write the metadata file")?;
println!("match_meta() should now return None again");
assert!(super::match_meta(&path, &path_meta)?.is_none());
println!("Writing the original metadata back");
fs::write(
&path_meta,
serde_json::to_string(&meta).context("Could not serialize the metadata")?,
)
.context("Could not write the metadata file")?;
println!("match_meta() should, once again, return something useful");
assert_eq!(
meta,
super::match_meta(&path, &path_meta)?.context("match_meta() should return something")?
);
println!("Modifying a header field should not cause match_meta() to return None");
let meta_mod = FileHttpMetadata {
file_size: meta_mod.file_size - 1,
hdr_last_modified: Some("hello there".to_owned()),
..meta_mod
};
fs::write(
&path_meta,
serde_json::to_string(&meta_mod).context("Could not serialize the metadata")?,
)
.context("Could not write the metadata file")?;
let meta_read =
super::match_meta(&path, &path_meta)?.context("match_meta() should return something")?;
assert_ne!(meta, meta_read);
let meta_read = FileHttpMetadata {
hdr_last_modified: None,
..meta_read
};
assert_eq!(meta, meta_read);
println!("Removing the data file");
fs::remove_file(&path).context("Could not remove the temporary file")?;
println!("match_meta() should return None again");
assert!(super::match_meta(&path, &path_meta)?.is_none());
println!("Looks like we reached the end of the trivial test sequence");
Ok(())
}
#[test]
#[allow(clippy::shadow_reuse)]
#[allow(clippy::shadow_unrelated)]
fn test_source() -> Result<()> {
let tempd_obj = tempfile::tempdir().context("Could not create a temporary directory")?;
let tempd: &Path = tempd_obj.as_ref();
println!("Using tempd {}", tempd.to_string_lossy());
let path = tempd.join("src-data.dat");
let path_meta = tempd.join("src-data.dat.metasrc");
let path_source = tempd.join("src-src.dat");
println!("match...source() should return empty with no files");
assert!(super::match_meta_with_source(&path, &path_meta, &path_source)?.is_none());
println!("from..source() should error out with no files");
FileHttpMetadata::from_file_with_source(&path, &path_source).unwrap_err();
println!("match...source() should return empty with no meta file");
assert!(super::match_meta_with_source(&path, &path_meta, &path_source)?.is_none());
fs::write(&path, "Hi there!").context("Could not create the temporary file")?;
println!("match...source() should return something even with no source file");
let meta = FileHttpMetadata::from_file(&path)
.context("Could not get the metadata for the temporary file")?;
assert!(meta.source_file_size.is_none());
assert!(meta.source_file_mtime.is_none());
fs::write(
&path_meta,
serde_json::to_string(&meta).context("Could not serialize the metadata")?,
)
.context("Could not write the metadata file")?;
let meta_read = super::match_meta_with_source(&path, &path_meta, &path_source)?
.context("match..source() with no source should still succeed")?;
assert_eq!(meta, meta_read);
println!("Now let us see what happens if we create a source file...");
fs::write(&path_source, "Something something something source file")
.context("Could not create the source file")?;
let meta_source = FileHttpMetadata::from_file(&path_source)
.context("Could not get the metadata for the source file")?;
let meta = FileHttpMetadata::from_file_with_source(&path, &path_source)
.context("Could not get the metadata for the temporary and source files")?;
assert_eq!(meta.source_file_size, Some(meta_source.file_size));
assert_eq!(meta.source_file_mtime, Some(meta_source.file_mtime));
assert_ne!(meta, meta_read);
assert_eq!(
meta,
FileHttpMetadata {
source_file_size: Some(meta_source.file_size),
source_file_mtime: Some(meta_source.file_mtime),
..meta_read
}
);
println!("Making sure match..with_source() also works");
fs::write(
&path_meta,
serde_json::to_string(&meta).context("Could not serialize the metadata")?,
)
.context("Could not write to the metadata file")?;
let meta_read = super::match_meta_with_source(&path, &path_meta, &path_source)?
.context("match..source() with no source should still succeed")?;
assert_eq!(meta, meta_read);
println!("Now let us remove the source file and see what happens");
fs::remove_file(&path_source).context("Could not remove the source file")?;
println!("match..source() should return None");
assert!(super::match_meta_with_source(&path, &path_meta, &path_source)?.is_none());
println!("from..source() should error out");
FileHttpMetadata::from_file_with_source(&path, &path_source).unwrap_err();
println!("from..source_meta() should still succeed");
let meta_read = FileHttpMetadata::from_file_with_source_meta(&path, &meta_source)
.context("Could not examine the temporary and missing source file")?;
assert_eq!(meta, meta_read);
println!("Replacing the metadata, forgetting about the source part");
let meta_read = FileHttpMetadata {
source_file_size: None,
source_file_mtime: None,
..meta_read
};
fs::write(
&path_meta,
serde_json::to_string(&meta_read).context("Could not serialize the metadata")?,
)
.context("Could not write to the metadata file")?;
let meta_read = super::match_meta_with_source(&path, &path_meta, &path_source)?
.context("match..source() with no source should still succeed")?;
assert_ne!(meta, meta_read);
assert_eq!(
meta,
FileHttpMetadata {
source_file_size: Some(meta_source.file_size),
source_file_mtime: Some(meta_source.file_mtime),
..meta_read
}
);
println!("Done with the source test sequence");
Ok(())
}
#[test]
fn test_default() {
let meta = FileHttpMetadata::default();
println!("default meta: {:?}", meta);
assert_eq!(meta.format.version.major, 0);
assert_eq!(meta.format.version.minor, 1);
assert_eq!(meta.file_size, 0);
assert_eq!(meta.file_mtime, 0);
assert!(meta.source_file_size.is_none());
assert!(meta.source_file_mtime.is_none());
}
#[test]
const fn test_send() {
const fn assert_send<T: Send>() {}
assert_send::<FileHttpMetadata>();
assert_send::<MetadataError>();
}
#[test]
const fn test_sync() {
const fn assert_sync<T: Sync>() {}
assert_sync::<FileHttpMetadata>();
assert_sync::<MetadataError>();
}
#[cfg(feature = "ureq")]
#[test]
fn test_build_req() -> Result<()> {
let tempd_obj = tempfile::tempdir().context("Could not create a temporary directory")?;
let tempd: &Path = tempd_obj.as_ref();
let path = tempd.join("triv-data.dat");
let path_meta = tempd.join("triv-data.dat.metatriv");
fs::write(&path, "this is a test").context("Could not create the temporary file")?;
let meta_raw = FileHttpMetadata::from_file(&path)
.context("Could not get the metadata for the temporary file")?;
assert_eq!(meta_raw.file_size, 14);
assert!(meta_raw.file_mtime > 0);
let req = ureq::get("https://example.com/");
assert!(req.header("If-None-Match").is_none());
assert!(req.header("If-Modified-Since").is_none());
let meta_last_mod = FileHttpMetadata {
hdr_last_modified: Some("today".to_owned()),
..meta_raw
};
fs::write(
&path_meta,
serde_json::to_string(&meta_last_mod)
.context("Could not serialize the metadata")?
.as_bytes(),
)
.context("Could not write to the metadata file")?;
assert_eq!(
super::match_meta(&path, &path_meta)?.unwrap(),
meta_last_mod
);
{
let (req_last_mod, meta_req_last_mod) = super::build_req(req.clone(), &path, &path_meta)?;
assert_eq!(meta_last_mod, meta_req_last_mod.unwrap());
assert!(req_last_mod.header("If-None-Match").is_none());
assert_eq!(req_last_mod.header("If-Modified-Since").unwrap(), "today");
}
let meta_etag_mod = FileHttpMetadata {
hdr_etag: Some("tagtag!".to_owned()),
..meta_last_mod
};
fs::write(
&path_meta,
serde_json::to_string(&meta_etag_mod)
.context("Could not serialize the metadata")?
.as_bytes(),
)
.context("Could not write to the metadata file")?;
assert_eq!(
super::match_meta(&path, &path_meta)?.unwrap(),
meta_etag_mod
);
{
let (req_etag_mod, meta_req_etag_mod) = super::build_req(req.clone(), &path, &path_meta)?;
assert_eq!(meta_etag_mod, meta_req_etag_mod.unwrap());
assert_eq!(req_etag_mod.header("If-None-Match").unwrap(), "tagtag!");
assert!(req_etag_mod.header("If-Modified-Since").is_none());
}
let meta_etag_only = FileHttpMetadata {
hdr_last_modified: None,
..meta_etag_mod
};
fs::write(
&path_meta,
serde_json::to_string(&meta_etag_only)
.context("Could not serialize the metadata")?
.as_bytes(),
)
.context("Could not write to the metadata file")?;
assert_eq!(
super::match_meta(&path, &path_meta)?.unwrap(),
meta_etag_only
);
{
let (req_etag_only, meta_req_etag_only) = super::build_req(req, &path, &path_meta)?;
assert_eq!(meta_etag_only, meta_req_etag_only.unwrap());
assert_eq!(req_etag_only.header("If-None-Match").unwrap(), "tagtag!");
assert!(req_etag_only.header("If-Modified-Since").is_none());
}
Ok(())
}