From b18b50cf235ba6ec3f52e033b7ab61240f9d2840 Mon Sep 17 00:00:00 2001 From: ginnyTheCat Date: Mon, 17 Feb 2025 13:15:55 +0100 Subject: [PATCH] Start implementing tests --- mupdf-sys/wrapper.c | 48 ++++++++++++++++++++++++ src/device.rs | 43 ++++++++++++++++++++- src/device/native.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) diff --git a/mupdf-sys/wrapper.c b/mupdf-sys/wrapper.c index 9ea2d8d..907087d 100644 --- a/mupdf-sys/wrapper.c +++ b/mupdf-sys/wrapper.c @@ -2863,6 +2863,54 @@ void mupdf_end_layer(fz_context *ctx, fz_device *device, mupdf_error_t **errptr) } } +void mupdf_begin_structure(fz_context *ctx, fz_device *device, fz_structure standard, const char *raw, int idx, mupdf_error_t **errptr) +{ + fz_try(ctx) + { + fz_begin_structure(ctx, device, standard, raw, idx); + } + fz_catch(ctx) + { + mupdf_save_error(ctx, errptr); + } +} + +void mupdf_end_structure(fz_context *ctx, fz_device *device, mupdf_error_t **errptr) +{ + fz_try(ctx) + { + fz_end_structure(ctx, device); + } + fz_catch(ctx) + { + mupdf_save_error(ctx, errptr); + } +} + +void mupdf_begin_metatext(fz_context *ctx, fz_device *device, fz_metatext meta, const char *text, mupdf_error_t **errptr) +{ + fz_try(ctx) + { + fz_begin_metatext(ctx, device, meta, text); + } + fz_catch(ctx) + { + mupdf_save_error(ctx, errptr); + } +} + +void mupdf_end_metatext(fz_context *ctx, fz_device *device, mupdf_error_t **errptr) +{ + fz_try(ctx) + { + fz_end_metatext(ctx, device); + } + fz_catch(ctx) + { + mupdf_save_error(ctx, errptr); + } +} + void mupdf_begin_mask(fz_context *ctx, fz_device *device, fz_rect area, bool luminosity, fz_colorspace *cs, const float *color, fz_color_params cp, mupdf_error_t **errptr) { fz_try(ctx) diff --git a/src/device.rs b/src/device.rs index 1a95a50..488dee7 100644 --- a/src/device.rs +++ b/src/device.rs @@ -114,7 +114,7 @@ pub enum Structure { Quote = fz_structure_FZ_STRUCTURE_QUOTE as _, Note = fz_structure_FZ_STRUCTURE_NOTE as _, Reference = fz_structure_FZ_STRUCTURE_REFERENCE as _, - Bibentry = fz_structure_FZ_STRUCTURE_BIBENTRY as _, + BibEntry = fz_structure_FZ_STRUCTURE_BIBENTRY as _, Code = fz_structure_FZ_STRUCTURE_CODE as _, Link = fz_structure_FZ_STRUCTURE_LINK as _, Annot = fz_structure_FZ_STRUCTURE_ANNOT as _, @@ -583,6 +583,47 @@ impl Device { } Ok(()) } + + pub fn begin_structure(&self, standard: Structure, raw: &str, idx: i32) -> Result<(), Error> { + let c_raw = CString::new(raw)?; + unsafe { + ffi_try!(mupdf_begin_structure( + context(), + self.dev, + standard as _, + c_raw.as_ptr(), + idx as _ + )); + } + Ok(()) + } + + pub fn end_structure(&self) -> Result<(), Error> { + unsafe { + ffi_try!(mupdf_end_structure(context(), self.dev)); + } + Ok(()) + } + + pub fn begin_metatext(&self, meta: Metatext, text: &str) -> Result<(), Error> { + let c_text = CString::new(text)?; + unsafe { + ffi_try!(mupdf_begin_metatext( + context(), + self.dev, + meta as _, + c_text.as_ptr() + )); + } + Ok(()) + } + + pub fn end_metatext(&self) -> Result<(), Error> { + unsafe { + ffi_try!(mupdf_end_metatext(context(), self.dev)); + } + Ok(()) + } } impl Drop for Device { diff --git a/src/device/native.rs b/src/device/native.rs index 39da22b..fd2829d 100644 --- a/src/device/native.rs +++ b/src/device/native.rs @@ -901,3 +901,92 @@ unsafe extern "C" fn end_metatext(_ctx: *mut fz_context, dev: * dev.end_metatext(); }); } + +#[cfg(test)] +mod test { + use std::rc::Rc; + + use crate::{ + device::{Metatext, Structure}, + Device, NativeDevice, + }; + + #[test] + fn native_device() { + #[derive(Default)] + struct Test { + begin_layer: u8, + end_layer: u8, + begin_structure: u8, + end_structure: u8, + begin_metatext: u8, + end_metatext: u8, + } + + impl NativeDevice for Test { + fn begin_layer(&mut self, name: &str) { + assert_eq!(name, "begin layer name"); + self.begin_layer += 1; + } + + fn end_layer(&mut self) { + self.end_layer += 1; + } + + fn begin_structure(&mut self, standard: Structure, raw: &str, idx: i32) { + assert_eq!(standard, Structure::Div); + assert_eq!(raw, "div"); + assert_eq!(idx, 5); + self.begin_structure += 1; + } + + fn end_structure(&mut self) { + self.end_structure += 1; + } + + fn begin_metatext(&mut self, meta: Metatext, text: &str) { + assert_eq!(meta, Metatext::Title); + assert_eq!(text, "some text"); + self.begin_metatext += 1; + } + + fn end_metatext(&mut self) { + self.end_metatext += 1; + } + } + + let mut ndev = Test::default(); + let dev = Device::from_native(&mut ndev); + + dev.begin_layer("begin layer name").unwrap(); + assert_eq!(ndev.begin_layer, 1); + dev.end_layer().unwrap(); + assert_eq!(ndev.end_layer, 1); + + dev.begin_structure(Structure::Div, "div", 5).unwrap(); + assert_eq!(ndev.begin_structure, 1); + dev.end_structure().unwrap(); + assert_eq!(ndev.end_structure, 1); + + dev.begin_metatext(Metatext::Title, "some text").unwrap(); + assert_eq!(ndev.begin_metatext, 1); + dev.end_metatext().unwrap(); + assert_eq!(ndev.end_metatext, 1); + } + + #[test] + fn native_device_drop() { + struct DropDevice(#[allow(dead_code)] Rc<()>); + + impl NativeDevice for DropDevice {} + + let proof = Rc::new(()); + let detector = proof.clone(); + assert_eq!(Rc::strong_count(&proof), 2, "setup failed"); + + let dev = Device::from_native(DropDevice(detector)); + assert_eq!(Rc::strong_count(&proof), 2, "dropped too early"); + drop(dev); + assert_eq!(Rc::strong_count(&proof), 1, "not dropped"); + } +}