diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c33bd65..883dc4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: - name: Generate code coverage env: RUST_BACKTRACE: "1" - run: cargo llvm-cov --all-features --lcov --output-path lcov.info + run: cargo llvm-cov --all-features --lcov --ignore-filename-regex tests --output-path lcov.info - name: Upload code coverage results uses: codecov/codecov-action@v3 diff --git a/src/lib.rs b/src/lib.rs index 4f0670b..71aa85d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,10 @@ #![doc = include_str!("../README.md")] mod ffi; + +#[cfg(test)] +mod tests; + mod xmp_date_time; mod xmp_file; mod xmp_meta; diff --git a/tests/fixtures/Purple Square.psd b/src/tests/fixtures/Purple Square.psd similarity index 100% rename from tests/fixtures/Purple Square.psd rename to src/tests/fixtures/Purple Square.psd diff --git a/src/tests/fixtures/mod.rs b/src/tests/fixtures/mod.rs new file mode 100644 index 0000000..f85193f --- /dev/null +++ b/src/tests/fixtures/mod.rs @@ -0,0 +1,38 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use std::{ + env, fs, + path::{Path, PathBuf}, +}; + +pub(crate) fn fixture_path(name: &str) -> String { + let root_dir = &env::var("CARGO_MANIFEST_DIR").unwrap(); + + let mut path = PathBuf::from(root_dir); + path.push("src/tests/fixtures"); + path.push(name); + + assert!(path.exists()); + + path.to_str().unwrap().to_string() +} + +pub(crate) fn temp_copy_of_fixture(tempdir: &Path, name: &str) -> String { + let fixture_src = fixture_path(name); + let fixture_path = Path::join(tempdir, name); + let fixture_copy = fixture_path.as_path(); + + fs::copy(fixture_src, fixture_copy).unwrap(); + fixture_copy.display().to_string() +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..f58ac99 --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,20 @@ +// Copyright 2022 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +// Tests are grouped under this module so as to avoid +// having the test code itself included in coverage numbers. + +mod fixtures; +mod xmp_date_time; +mod xmp_file; +mod xmp_meta; diff --git a/src/tests/xmp_date_time.rs b/src/tests/xmp_date_time.rs new file mode 100644 index 0000000..6b71267 --- /dev/null +++ b/src/tests/xmp_date_time.rs @@ -0,0 +1,24 @@ +// Copyright 2020 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use crate::XmpDateTime; + +#[test] +fn new_empty() { + let mut _dt = XmpDateTime::new(); +} + +#[test] +fn current() { + let mut _dt = XmpDateTime::current(); +} diff --git a/src/tests/xmp_file.rs b/src/tests/xmp_file.rs new file mode 100644 index 0000000..de804c4 --- /dev/null +++ b/src/tests/xmp_file.rs @@ -0,0 +1,93 @@ +// Copyright 2020 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use std::path::PathBuf; + +use tempfile::tempdir; + +use crate::{tests::fixtures::*, xmp_ns, OpenFileOptions, XmpDateTime, XmpFile, XmpMeta}; + +#[test] +fn open_and_edit_file() { + let tempdir = tempdir().unwrap(); + let purple_square = temp_copy_of_fixture(tempdir.path(), "Purple Square.psd"); + + { + let mut f = XmpFile::new(); + + assert!(f + .open_file( + &purple_square, + OpenFileOptions::default().for_update().use_smart_handler() + ) + .is_ok()); + + let opt_m = f.xmp(); + assert!(opt_m.is_some()); + + XmpMeta::register_namespace("http://purl.org/dc/terms/", "dcterms"); + + let mut m = opt_m.unwrap(); + m.set_property("http://purl.org/dc/terms/", "provenance", "blah"); + + assert!(m.does_property_exist("http://purl.org/dc/terms/", "provenance")); + assert!(!m.does_property_exist("http://purl.org/dc/terms/", "provenancx")); + + if m.does_property_exist(xmp_ns::XMP, "MetadataDate") { + let updated_time = XmpDateTime::current(); + m.set_property_date(xmp_ns::XMP, "MetadataDate", &updated_time); + } + + assert!(f.can_put_xmp(&m)); + f.put_xmp(&m); + + f.close(); + } + + // Let's make sure we actually wrote to the file. + { + let mut f = XmpFile::new(); + + assert!(f + .open_file( + &purple_square, + OpenFileOptions::default().for_update().use_smart_handler() + ) + .is_ok()); + + let m = f.xmp().unwrap(); + + assert_eq!( + m.property("http://purl.org/dc/terms/", "provenance") + .unwrap(), + "blah" + ); + assert_eq!(m.property("http://purl.org/dc/terms/", "provenancx"), None); + } +} + +#[test] +fn open_fail() { + let bad_path = PathBuf::from("doesnotexist.jpg"); + + { + let mut f = XmpFile::new(); + + assert!(f + .open_file( + &bad_path, + OpenFileOptions::default().for_update().use_smart_handler() + ) + .is_err()); + } +} diff --git a/src/tests/xmp_meta.rs b/src/tests/xmp_meta.rs new file mode 100644 index 0000000..faee18e --- /dev/null +++ b/src/tests/xmp_meta.rs @@ -0,0 +1,48 @@ +// Copyright 2020 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, +// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +// or the MIT license (http://opensource.org/licenses/MIT), +// at your option. + +// Unless required by applicable law or agreed to in writing, +// this software is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or +// implied. See the LICENSE-MIT and LICENSE-APACHE files for the +// specific language governing permissions and limitations under +// each license. + +use crate::{tests::fixtures::*, XmpMeta}; + +#[test] +fn new_empty() { + let mut _m = XmpMeta::new(); +} + +#[test] +fn from_file() { + let m = XmpMeta::from_file(fixture_path("Purple Square.psd")).unwrap(); + + assert_eq!( + m.property("http://ns.adobe.com/xap/1.0/", "CreatorTool") + .unwrap(), + "Adobe Photoshop CS2 Windows" + ); + + assert_eq!( + m.property("http://ns.adobe.com/photoshop/1.0/", "ICCProfile") + .unwrap(), + "Dell 1905FP Color Profile" + ); + + assert!(m + .property("http://ns.adobe.com/photoshop/1.0/", "ICCProfilx") + .is_none()); +} + +#[test] +fn register_namespace() { + assert_eq!( + XmpMeta::register_namespace("http://purl.org/dc/terms/", "dcterms"), + "dcterms:" + ); +} diff --git a/src/xmp_date_time.rs b/src/xmp_date_time.rs index 5ae5b4f..f34896f 100644 --- a/src/xmp_date_time.rs +++ b/src/xmp_date_time.rs @@ -50,18 +50,3 @@ impl XmpDateTime { } } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn new_empty() { - let mut _dt = XmpDateTime::new(); - } - - #[test] - fn current() { - let mut _dt = XmpDateTime::current(); - } -} diff --git a/src/xmp_file.rs b/src/xmp_file.rs index 03aa0b5..a85b0b7 100644 --- a/src/xmp_file.rs +++ b/src/xmp_file.rs @@ -282,110 +282,3 @@ fn path_to_cstr(path: &Path) -> Option { None => None, } } - -#[cfg(test)] -mod tests { - use super::*; - - use std::{ - env, fs, - path::{Path, PathBuf}, - }; - - use tempfile::tempdir; - - use crate::{xmp_ns, XmpDateTime}; - - fn fixture_path(name: &str) -> String { - let root_dir = &env::var("CARGO_MANIFEST_DIR").unwrap(); - - let mut path = PathBuf::from(root_dir); - path.push("tests/fixtures"); - path.push(name); - path.to_str().unwrap().to_string() - } - - fn temp_copy_of_fixture(tempdir: &Path, name: &str) -> String { - let fixture_src = fixture_path(name); - let fixture_path = Path::join(tempdir, name); - let fixture_copy = fixture_path.as_path(); - - fs::copy(fixture_src, fixture_copy).unwrap(); - fixture_copy.display().to_string() - } - - #[test] - fn open_and_edit_file() { - let tempdir = tempdir().unwrap(); - let purple_square = temp_copy_of_fixture(tempdir.path(), "Purple Square.psd"); - - { - let mut f = XmpFile::new(); - - assert!(f - .open_file( - &purple_square, - OpenFileOptions::default().for_update().use_smart_handler() - ) - .is_ok()); - - let opt_m = f.xmp(); - assert!(opt_m.is_some()); - - XmpMeta::register_namespace("http://purl.org/dc/terms/", "dcterms"); - - let mut m = opt_m.unwrap(); - m.set_property("http://purl.org/dc/terms/", "provenance", "blah"); - - assert!(m.does_property_exist("http://purl.org/dc/terms/", "provenance")); - assert!(!m.does_property_exist("http://purl.org/dc/terms/", "provenancx")); - - if m.does_property_exist(xmp_ns::XMP, "MetadataDate") { - let updated_time = XmpDateTime::current(); - m.set_property_date(xmp_ns::XMP, "MetadataDate", &updated_time); - } - - assert!(f.can_put_xmp(&m)); - f.put_xmp(&m); - - f.close(); - } - - // Let's make sure we actually wrote to the file. - { - let mut f = XmpFile::new(); - - assert!(f - .open_file( - &purple_square, - OpenFileOptions::default().for_update().use_smart_handler() - ) - .is_ok()); - - let m = f.xmp().unwrap(); - - assert_eq!( - m.property("http://purl.org/dc/terms/", "provenance") - .unwrap(), - "blah" - ); - assert_eq!(m.property("http://purl.org/dc/terms/", "provenancx"), None); - } - } - - #[test] - fn open_fail() { - let bad_path = PathBuf::from("doesnotexist.jpg"); - - { - let mut f = XmpFile::new(); - - assert!(f - .open_file( - &bad_path, - OpenFileOptions::default().for_update().use_smart_handler() - ) - .is_err()); - } - } -} diff --git a/src/xmp_meta.rs b/src/xmp_meta.rs index 28eed53..80b384a 100644 --- a/src/xmp_meta.rs +++ b/src/xmp_meta.rs @@ -201,52 +201,3 @@ impl XmpMeta { r != 0 } } - -#[cfg(test)] -mod tests { - use super::*; - - use std::{env, path::PathBuf}; - - fn fixture_path(name: &str) -> PathBuf { - let root_dir = &env::var("CARGO_MANIFEST_DIR").unwrap(); - let mut path = PathBuf::from(root_dir); - path.push("tests/fixtures"); - path.push(name); - path - } - - #[test] - fn new_empty() { - let mut _m = XmpMeta::new(); - } - - #[test] - fn from_file() { - let m = XmpMeta::from_file(fixture_path("Purple Square.psd")).unwrap(); - - assert_eq!( - m.property("http://ns.adobe.com/xap/1.0/", "CreatorTool") - .unwrap(), - "Adobe Photoshop CS2 Windows" - ); - - assert_eq!( - m.property("http://ns.adobe.com/photoshop/1.0/", "ICCProfile") - .unwrap(), - "Dell 1905FP Color Profile" - ); - - assert!(m - .property("http://ns.adobe.com/photoshop/1.0/", "ICCProfilx") - .is_none()); - } - - #[test] - fn register_namespace() { - assert_eq!( - XmpMeta::register_namespace("http://purl.org/dc/terms/", "dcterms"), - "dcterms:" - ); - } -}