use std::sync::{Arc, Mutex};
use psdk_father::types::psdk_types::PsdkPrinterCommandEnumValue;
use psdk_father::{
command::PsdkCommand, device::FakeConnectedDevice, psdk::Psdk, types::psdk_types::Lifecycle,
};
use psdk_fruit_cpcl::args::{
CBar, CBarOptions, CBox, CBoxOptions, CImagePixels, CImagePixelsOptions, CInverse,
CInverseOptions, CLine, CLineOptions, CMag, CMagOptions, CPage, CPageHeight, CPageHeightOptions,
CPageMode, CPageModeOptions, CPageOptions, CPageWidth, CPageWidthOptions, CPrint, CPrintOptions,
CQRCode, CQRCodeOptions, CText, CTextOptions, CWaterMark, CWaterMarkOptions, Location,
ThresholdEdgeDitherDepth, ThresholdEdgeDitherMode,
};
#[cfg(feature = "image-plus")]
use psdk_fruit_cpcl::args::{
CImageBytes, CImageBytesOptions, CTextCanvas, CTextCanvasImageOptions, CTextCanvasOptions,
};
use psdk_fruit_cpcl::marks::{CodeRotation, CodeType, CorrectLevel, Font, Mode, Rotation};
use psdk_fruit_cpcl::BaseCpcl;
mod common;
fn command_string(command: &mut BaseCpcl) -> String {
command.command().unwrap().string().unwrap()
}
fn command_binary(command: &mut BaseCpcl) -> Vec<u8> {
command.command().unwrap().binary().to_vec()
}
fn contains_bytes(bytes: &[u8], expected: &[u8]) -> bool {
bytes
.windows(expected.len())
.any(|window| window == expected)
}
#[test]
fn test_mark_values_match_dart_extensions() {
assert_eq!(CodeType::Code39.command_value(), "39");
assert_eq!(CodeType::Code128.command_value(), "128");
assert_eq!(CodeType::Code93.command_value(), "93");
assert_eq!(CodeType::Codabar.command_value(), "CODABAR");
assert_eq!(CodeType::Ean8.command_value(), "EAN8");
assert_eq!(CodeType::Ean13.command_value(), "EAN13");
assert_eq!(CodeType::Upca.command_value(), "UPCA");
assert_eq!(CodeType::Upce.command_value(), "UPCE");
assert_eq!(CodeType::I2Of5.command_value(), "I2OF5");
assert_eq!(CodeType::I20F5.command_value(), "I2OF5");
assert_eq!(CodeRotation::Rotation0.command_value(), "B");
assert_eq!(CodeRotation::Rotation90.command_value(), "VB");
assert_eq!(Font::Tss16.get_ex(), 1);
assert_eq!(Font::Tss16.get_ey(), 1);
assert_eq!(Font::Tss16.get_family(), 55);
assert_eq!(Font::Tss16.get_size(), 0);
assert_eq!(Font::Tss16.get_height(), 16);
assert_eq!(Font::Tss20Max1.get_ex(), 2);
assert_eq!(Font::Tss20Max1.get_height(), 40);
assert_eq!(Font::Tss24Max2.get_ex(), 3);
assert_eq!(Font::Tss24Max2.get_height(), 72);
assert_eq!(Font::Tss28Max2.get_family(), 7);
assert_eq!(Font::Tss32Max2.get_family(), 4);
assert_eq!(Rotation::Rotation0.command_value(), "");
assert_eq!(Rotation::Rotation90.command_value(), "90");
assert_eq!(Rotation::Rotation180.command_value(), "180");
assert_eq!(Rotation::Rotation270.command_value(), "270");
assert_eq!(Mode::Normal.get_mode(), 0);
assert_eq!(Mode::Horizontal.get_mode(), 1);
assert_eq!(Mode::Mirror.get_mode(), 2);
assert_eq!(CorrectLevel::L.get_level(), "L");
assert_eq!(CorrectLevel::M.get_level(), "M");
assert_eq!(CorrectLevel::Q.get_level(), "Q");
assert_eq!(CorrectLevel::H.get_level(), "H");
assert_eq!(CorrectLevel::L.get_level_num(), 0);
assert_eq!(CorrectLevel::M.get_level_num(), 1);
assert_eq!(CorrectLevel::Q.get_level_num(), 2);
assert_eq!(CorrectLevel::H.get_level_num(), 3);
}
#[test]
fn test_font_values_match_dart_extensions() {
let cases = [
(Font::Tss16, 1, 1, 55, 0, 16),
(Font::Tss20, 1, 1, 6, 0, 20),
(Font::Tss20Max1, 2, 2, 6, 0, 40),
(Font::Tss24, 1, 1, 24, 0, 24),
(Font::Tss28, 1, 1, 7, 0, 28),
(Font::Tss32, 1, 1, 4, 0, 32),
(Font::Tss24Max1, 2, 2, 24, 0, 48),
(Font::Tss28Max1, 2, 2, 7, 0, 56),
(Font::Tss32Max1, 2, 2, 4, 0, 64),
(Font::Tss24Max2, 3, 3, 24, 0, 72),
(Font::Tss28Max2, 3, 3, 7, 0, 84),
(Font::Tss32Max2, 3, 3, 4, 0, 96),
];
for (font, ex, ey, family, size, height) in cases {
assert_eq!(font.get_ex(), ex);
assert_eq!(font.get_ey(), ey);
assert_eq!(font.get_family(), family);
assert_eq!(font.get_size(), size);
assert_eq!(font.get_height(), height);
}
}
#[test]
fn test_dart_style_constructors() {
let device = Arc::new(Mutex::new(FakeConnectedDevice::new()));
let mut cpcl = BaseCpcl::with_connected_device(device);
cpcl.form().unwrap();
assert_eq!(command_string(&mut cpcl), "FORM\r\n");
let mut cpcl = BaseCpcl::with_lifecycle(Lifecycle::simple(Arc::new(Mutex::new(
FakeConnectedDevice::new(),
))));
cpcl.feed().unwrap();
assert_eq!(
command_string(&mut cpcl),
"! 0 200 200 0 1 \r\nPAGE-WIDTH 576\r\nGAP-SENSE\r\nFORM\r\nPRINT\r\n"
);
}
#[test]
fn test_dart_parity_simple_base_commands() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.status()
.unwrap()
.sn()
.unwrap()
.model()
.unwrap()
.version()
.unwrap()
.battery_volume()
.unwrap();
assert_eq!(
command_binary(&mut command),
vec![
0x10, 0x04, 0x05, 0x10, 0xff, 0xef, 0xf2, 0x10, 0xff, 0xef, 0xf0, 0x10, 0xff, 0xef, 0xf1,
0x10, 0xff, 0xef, 0xf3,
]
);
let mut command = BaseCpcl::new(common::lifecycle());
command.bold(true).unwrap().underline(false).unwrap();
assert_eq!(
command_string(&mut command),
"SETBOLD 1\r\nUNDERLINE OFF\r\n"
);
}
#[cfg(feature = "image-plus")]
fn png_1x1() -> Vec<u8> {
vec![
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4,
0x89, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00,
0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
0x42, 0x60, 0x82,
]
}
#[test]
fn test_qrcode_builds_dart_fixture_block() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.qrcode(CQRCode::new(CQRCodeOptions {
x: 0,
y: 0,
content: "10000".to_string(),
code_rotation: None,
width: 10,
level: Some(CorrectLevel::L),
}))
.unwrap();
assert_eq!(
command_string(&mut command),
"SETQRVER 0\nB QR 0 0 M 2 U 10\nLA,10000\nENDQR\r\n",
);
}
#[test]
fn test_qrcode_uses_utf8_charset_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.qrcode(CQRCode::new(CQRCodeOptions {
x: 0,
y: 0,
content: "ä½ å¥½".to_string(),
code_rotation: None,
width: 10,
level: Some(CorrectLevel::L),
}))
.unwrap();
let bytes = command_binary(&mut command);
assert!(contains_bytes(&bytes, "ä½ å¥½".as_bytes()));
}
#[test]
fn test_text_and_bar_use_default_gbk_charset_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.text(CText::new(CTextOptions {
font: Some(Font::Tss16),
x: 1,
y: 2,
content: "ä½ å¥½".to_string(),
bold: None,
underline: None,
mag: None,
rotation: Some(Rotation::Rotation0),
}))
.unwrap()
.bar(CBar::new(CBarOptions {
x: 3,
y: 4,
content: "ä½ å¥½".to_string(),
line_width: 2,
height: 30,
code_type: None,
code_rotation: None,
}))
.unwrap();
let bytes = command_binary(&mut command);
assert!(contains_bytes(&bytes, &[0xc4, 0xe3, 0xba, 0xc3]));
assert!(!contains_bytes(&bytes, "ä½ å¥½".as_bytes()));
}
#[test]
fn test_box_builds_dart_fixture_command() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.box_(CBox::new(CBoxOptions {
line_width: 2,
top_left_x: 0,
top_left_y: 0,
bottom_right_x: 200,
bottom_right_y: 100,
}))
.unwrap();
assert_eq!(command_string(&mut command), "BOX 0 0 200 100 2\r\n");
}
#[test]
fn test_box_clamps_x_coordinates_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.box_(CBox::new(CBoxOptions {
line_width: 2,
top_left_x: 600,
top_left_y: 0,
bottom_right_x: 700,
bottom_right_y: 100,
}))
.unwrap();
assert_eq!(command_string(&mut command), "BOX 575 0 575 100 2\r\n");
}
#[test]
fn test_coordinate_args_accept_signed_values_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.box_(CBox::new(CBoxOptions {
line_width: 2,
top_left_x: -1,
top_left_y: -2,
bottom_right_x: 700,
bottom_right_y: -4,
}))
.unwrap()
.bar(CBar::new(psdk_fruit_cpcl::args::CBarOptions {
x: -5,
y: -6,
content: "123".to_string(),
line_width: 2,
height: 30,
code_type: None,
code_rotation: None,
}))
.unwrap()
.qrcode(CQRCode::new(CQRCodeOptions {
x: -7,
y: -8,
content: "qr".to_string(),
code_rotation: None,
width: 4,
level: Some(CorrectLevel::L),
}))
.unwrap()
.inverse(CInverse::new(CInverseOptions {
x: -9,
y: -10,
font: Some(Font::Tss16),
content: "a".to_string(),
rotation: Some(Rotation::Rotation0),
}))
.unwrap()
.image(CImagePixels::new(CImagePixelsOptions {
x: -11,
y: -12,
pixels: vec![0xff, 0xff, 0xff, 0xff],
width: 1,
height: 1,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
}))
.unwrap();
assert_eq!(
command_string(&mut command),
concat!(
"BOX -1 -2 575 -4 2\r\n",
"B 128 2 2 30 -5 -6 123\r\n",
"SETQRVER 0\nB QR -7 -8 M 2 U 4\nLA,qr\nENDQR\r\n",
"INVERSE-LINE -9 -10 -1 -10 16\r\n",
"CG 1 1 -11 -12 \u{0}\r\n\r\n",
)
);
}
#[test]
fn test_page_line_print_builds_dart_fixture_sequence() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page(CPage::new(CPageOptions {
width: 500,
height: 600,
copies: 1,
}))
.unwrap()
.line(CLine::new(CLineOptions {
line_width: 2,
start_x: 0,
start_y: 240,
end_x: 584,
end_y: 240,
is_solid_line: false,
}))
.unwrap()
.print(CPrint::new(CPrintOptions { mode: None }))
.unwrap();
assert_eq!(
command_string(&mut command),
"! 0 200 200 600 1\r\nPAGE-WIDTH 500\r\nLP 0 240 584 240 3\r\nPRINT\r\n",
);
}
#[test]
fn test_line_accepts_signed_coordinates_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.line(CLine::new(CLineOptions {
line_width: 2,
start_x: -1,
start_y: -2,
end_x: 3,
end_y: -4,
is_solid_line: true,
}))
.unwrap();
assert_eq!(command_string(&mut command), "L -1 -2 3 -4 3\r\n");
}
#[test]
fn test_print_horizontal_matches_dart_command() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.print(CPrint::new(CPrintOptions {
mode: Some(psdk_fruit_cpcl::marks::Mode::Horizontal),
}))
.unwrap();
assert_eq!(command_string(&mut command), "POPRINT\r\n");
}
#[test]
fn test_dart_style_print_method_accepts_mode() {
let mut wrapped_command = BaseCpcl::new(common::lifecycle());
let mut explicit_command = BaseCpcl::new(common::lifecycle());
wrapped_command
.print(psdk_fruit_cpcl::marks::Mode::Horizontal)
.unwrap();
explicit_command
.print(CPrint::new(CPrintOptions {
mode: Some(psdk_fruit_cpcl::marks::Mode::Horizontal),
}))
.unwrap();
assert_eq!(
command_string(&mut wrapped_command),
command_string(&mut explicit_command)
);
}
#[test]
fn test_print_default_and_water_mark_value_match_dart_wrappers() {
let mut command = BaseCpcl::new(common::lifecycle());
command.print_default().unwrap().water_mark(-8).unwrap();
assert_eq!(command_string(&mut command), "PRINT\r\nWAT -8\r\n");
}
#[test]
fn test_dart_style_default_args_match_dart_constructors() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.print(CPrint::default())
.unwrap()
.page_mode(CPageMode::default())
.unwrap()
.mag(CMag::default())
.unwrap();
assert_eq!(command_string(&mut command), "PRINT\r\nSETMAG 1 1\r\n");
}
#[test]
fn test_dart_style_page_mode_and_mag_methods_accept_enums() {
let mut wrapped_command = BaseCpcl::new(common::lifecycle());
let mut explicit_command = BaseCpcl::new(common::lifecycle());
wrapped_command
.page_mode(Location::Skip)
.unwrap()
.mag(Font::Tss28Max1)
.unwrap();
explicit_command
.page_mode(CPageMode::new(CPageModeOptions {
location: Location::Skip,
}))
.unwrap()
.mag(CMag::new(CMagOptions {
font: Some(Font::Tss28Max1),
}))
.unwrap();
assert_eq!(
command_string(&mut wrapped_command),
command_string(&mut explicit_command)
);
}
#[test]
fn test_dart_style_page_wrappers_use_default_copies() {
let mut command = BaseCpcl::new(common::lifecycle());
command.page((600, 500)).unwrap().page_height(300).unwrap();
assert_eq!(
command_string(&mut command),
"! 0 200 200 600 1\r\nPAGE-WIDTH 500\r\n! 0 200 200 300 1\r\n"
);
}
#[test]
fn test_dart_style_content_and_shape_wrappers_use_default_args() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.bar((1, 2, "123", 2, 30))
.unwrap()
.inverse((10, 20, "hi"))
.unwrap()
.line((1, 2, 3, 4, 5))
.unwrap()
.qrcode((6, 7, "qr", 8))
.unwrap()
.text((9, 10, "txt"))
.unwrap();
assert_eq!(
command_string(&mut command),
concat!(
"B 128 2 2 30 1 2 123\r\n",
"INVERSE-LINE 10 20 26 20 16\r\n",
"L 2 3 4 5 2\r\n",
"SETQRVER 0\nB QR 6 7 M 2 U 8\nLA,qr\nENDQR\r\n",
"T 55 0 9 10 txt\r\n",
)
);
}
#[test]
fn test_clear_resets_buffer() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.box_(CBox::new(CBoxOptions {
line_width: 2,
top_left_x: 0,
top_left_y: 0,
bottom_right_x: 200,
bottom_right_y: 100,
}))
.unwrap();
command.clear();
assert_eq!(command.command().unwrap().binary(), &[]);
}
#[test]
fn test_text_with_mag_prepends_setmag_for_selected_font() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.text(CText::new(CTextOptions {
font: Some(Font::Tss28Max1),
x: 12,
y: 34,
content: "hello".to_string(),
bold: None,
underline: None,
mag: Some(true),
rotation: Some(Rotation::Rotation0),
}))
.unwrap();
assert_eq!(
command_string(&mut command),
"SETMAG 2 2\r\nT 7 0 12 34 hello\r\n"
);
}
#[test]
fn test_text_uses_dart_tss20_font_family() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.text(CText::new(CTextOptions {
font: Some(Font::Tss20),
x: 12,
y: 34,
content: "hello".to_string(),
bold: None,
underline: None,
mag: None,
rotation: Some(Rotation::Rotation0),
}))
.unwrap();
assert_eq!(command_string(&mut command), "T 6 0 12 34 hello\r\n");
}
#[test]
fn test_text_accepts_signed_coordinates_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.text(CText::new(CTextOptions {
font: Some(Font::Tss16),
x: -1,
y: -2,
content: "hello".to_string(),
bold: None,
underline: None,
mag: None,
rotation: Some(Rotation::Rotation0),
}))
.unwrap();
assert_eq!(command_string(&mut command), "T 55 0 -1 -2 hello\r\n");
}
#[test]
fn test_page_width_wrapper_builds_dart_command() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page_width(CPageWidth::new(CPageWidthOptions { width: 500 }))
.unwrap();
assert_eq!(command_string(&mut command), "PAGE-WIDTH 500\r\n");
}
#[test]
fn test_dart_style_box_and_page_width_methods_accept_tuple_and_width() {
let mut command = BaseCpcl::new(common::lifecycle());
let mut expected = BaseCpcl::new(common::lifecycle());
command
.box_((2, 0, 0, 200, 100))
.unwrap()
.page_width(500)
.unwrap();
expected
.box_(CBox::new(CBoxOptions {
line_width: 2,
top_left_x: 0,
top_left_y: 0,
bottom_right_x: 200,
bottom_right_y: 100,
}))
.unwrap()
.page_width(CPageWidth::new(CPageWidthOptions { width: 500 }))
.unwrap();
assert_eq!(command_string(&mut command), command_string(&mut expected));
}
#[test]
fn test_page_height_wrapper_builds_dart_command() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page_height(CPageHeight::new(CPageHeightOptions {
height: 600,
copies: 1,
}))
.unwrap();
assert_eq!(command_string(&mut command), "! 0 200 200 600 1\r\n");
}
#[test]
fn test_page_height_copies_accept_signed_values_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page_height(CPageHeight::new(CPageHeightOptions {
height: 100,
copies: -3,
}))
.unwrap();
assert_eq!(command_string(&mut command), "! 0 200 200 100 -3\r\n");
}
#[test]
fn test_text_size_args_accept_signed_values_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page(CPage::new(CPageOptions {
height: -10,
width: -20,
copies: -2,
}))
.unwrap()
.bar(CBar::new(CBarOptions {
x: 1,
y: 2,
content: "123".to_string(),
line_width: -3,
height: -4,
code_type: None,
code_rotation: None,
}))
.unwrap()
.box_(CBox::new(CBoxOptions {
line_width: -5,
top_left_x: 1,
top_left_y: 2,
bottom_right_x: 3,
bottom_right_y: 4,
}))
.unwrap()
.line(CLine::new(CLineOptions {
line_width: -6,
start_x: 1,
start_y: 2,
end_x: 3,
end_y: 4,
is_solid_line: true,
}))
.unwrap()
.qrcode(CQRCode::new(CQRCodeOptions {
x: 1,
y: 2,
content: "qr".to_string(),
code_rotation: None,
width: -7,
level: None,
}))
.unwrap()
.water_mark(CWaterMark::new(CWaterMarkOptions {
mark_type: 0,
value: -8,
}))
.unwrap();
assert_eq!(
command_string(&mut command),
concat!(
"! 0 200 200 -10 -2\r\n",
"PAGE-WIDTH -20\r\n",
"B 128 -3 2 -4 1 2 123\r\n",
"BOX 1 2 3 4 -5\r\n",
"L 1 2 3 4 -5\r\n",
"SETQRVER 0\nB QR 1 2 M 2 U -7\nLA,qr\nENDQR\r\n",
"WAT -8\r\n"
)
);
}
#[test]
fn test_page_mode_no_location_matches_dart_empty_output() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page_mode(CPageMode::new(CPageModeOptions {
location: Location::NoLocation,
}))
.unwrap();
assert_eq!(command_string(&mut command), "");
}
#[test]
fn test_page_mode_skip_matches_dart_form_sequence() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.page_mode(CPageMode::new(CPageModeOptions {
location: Location::Skip,
}))
.unwrap();
assert_eq!(command_string(&mut command), "GAP-SENSE\r\nFORM\r\n");
}
#[test]
fn test_water_mark_matches_dart_value_only_command() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.water_mark(CWaterMark::new(CWaterMarkOptions {
mark_type: 9,
value: 128,
}))
.unwrap();
assert_eq!(command_string(&mut command), "WAT 128\r\n");
}
#[test]
fn test_feed_matches_dart_actual_output() {
let mut command = BaseCpcl::new(common::lifecycle());
command.feed().unwrap();
assert_eq!(
command_string(&mut command),
"! 0 200 200 0 1 \r\nPAGE-WIDTH 576\r\nGAP-SENSE\r\nFORM\r\nPRINT\r\n",
);
}
#[test]
fn test_single_command_inverse() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.inverse(CInverse::new(CInverseOptions {
x: 10,
y: 20,
font: Some(Font::Tss16),
content: "hello world".to_string(),
rotation: Some(Rotation::Rotation0),
}))
.unwrap();
assert_eq!(
command_string(&mut command),
"INVERSE-LINE 10 20 98 20 16\r\n"
);
}
#[test]
fn test_inverse_allows_negative_coordinates_like_dart() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.inverse(CInverse::new(CInverseOptions {
x: 10,
y: 20,
font: Some(Font::Tss16),
content: "hello world".to_string(),
rotation: Some(Rotation::Rotation90),
}))
.unwrap();
assert_eq!(
command_string(&mut command),
"INVERSE-LINE 10 -68 26 -68 88\r\n"
);
}
#[test]
fn test_inverse_uses_dart_string_length_for_unicode_content() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.inverse(CInverse::new(CInverseOptions {
x: 10,
y: 20,
font: Some(Font::Tss16),
content: "ä½ å¥½".to_string(),
rotation: Some(Rotation::Rotation0),
}))
.unwrap();
assert_eq!(
command_string(&mut command),
"INVERSE-LINE 10 20 26 20 16\r\n"
);
}
#[test]
fn test_image_alias_matches_image_pixels() {
let options = CImagePixelsOptions {
x: 1,
y: 2,
pixels: {
let mut pixels = Vec::new();
pixels.extend_from_slice(&[0x00, 0x00, 0x00, 0xff]);
for _ in 1..8 {
pixels.extend_from_slice(&[0xff, 0xff, 0xff, 0xff]);
}
pixels
},
width: 8,
height: 1,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
};
let mut image_command = BaseCpcl::new(common::lifecycle());
let mut image_pixels_command = BaseCpcl::new(common::lifecycle());
image_command
.image(CImagePixels::new(options.clone()))
.unwrap();
image_pixels_command
.image_pixels(CImagePixels::new(options))
.unwrap();
assert_eq!(
command_binary(&mut image_command),
command_binary(&mut image_pixels_command)
);
}
#[test]
fn test_dart_style_image_pixel_wrapper_uses_default_args() {
let pixels = vec![0xff, 0xff, 0xff, 0xff];
let mut wrapped_command = BaseCpcl::new(common::lifecycle());
wrapped_command
.image((1, 2, pixels.clone(), 1, 1))
.unwrap()
.image_pixels((3, 4, pixels.clone(), 1, 1))
.unwrap();
let mut explicit_command = BaseCpcl::new(common::lifecycle());
explicit_command
.image(CImagePixels::new(CImagePixelsOptions {
x: 1,
y: 2,
pixels: pixels.clone(),
width: 1,
height: 1,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
}))
.unwrap()
.image_pixels(CImagePixels::new(CImagePixelsOptions {
x: 3,
y: 4,
pixels,
width: 1,
height: 1,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
}))
.unwrap();
assert_eq!(
command_binary(&mut wrapped_command),
command_binary(&mut explicit_command)
);
}
#[cfg(feature = "image-plus")]
#[test]
fn test_dart_style_image_bytes_and_text_canvas_wrappers_use_default_args() {
let image = png_1x1();
let mut wrapped_command = BaseCpcl::new(common::lifecycle());
wrapped_command
.image_bytes((1, 2, image.clone()))
.unwrap()
.text_canvas((3, 4, image.clone()))
.unwrap();
let mut explicit_command = BaseCpcl::new(common::lifecycle());
explicit_command
.image_bytes(
CImageBytes::new(CImageBytesOptions {
x: 1,
y: 2,
bytes: image.clone(),
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
})
.unwrap(),
)
.unwrap()
.text_canvas(
CTextCanvas::new(CTextCanvasOptions {
x: 3,
y: 4,
image_bytes: image,
compress: false,
})
.unwrap(),
)
.unwrap();
assert_eq!(
command_binary(&mut wrapped_command),
command_binary(&mut explicit_command)
);
}
#[test]
fn test_compressed_image_x_matches_dart_byte_offset() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.image(CImagePixels::new(CImagePixelsOptions {
x: 8,
y: 2,
pixels: {
let mut pixels = Vec::new();
pixels.extend_from_slice(&[0x00, 0x00, 0x00, 0xff]);
for _ in 1..8 {
pixels.extend_from_slice(&[0xff, 0xff, 0xff, 0xff]);
}
pixels
},
width: 8,
height: 1,
compress: true,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
}))
.unwrap();
assert!(command_binary(&mut command).starts_with(b"ZG 1 1 1 2 "));
}
#[cfg(feature = "image-plus")]
#[test]
fn test_text_canvas_matches_dart_image_wrapper() {
let image = png_1x1();
let mut text_canvas_command = BaseCpcl::new(common::lifecycle());
let mut image_command = BaseCpcl::new(common::lifecycle());
text_canvas_command
.text_canvas(
CTextCanvas::new(CTextCanvasOptions {
x: 1,
y: 2,
image_bytes: image.clone(),
compress: false,
})
.unwrap(),
)
.unwrap();
image_command
.image_bytes(
CImageBytes::new(CImageBytesOptions {
x: 1,
y: 2,
bytes: image,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
})
.unwrap(),
)
.unwrap();
assert_eq!(
command_binary(&mut text_canvas_command),
command_binary(&mut image_command)
);
}
#[cfg(feature = "image-plus")]
#[test]
fn test_text_canvas_generates_image_bytes_like_dart_helper() {
let image = CTextCanvas::generate_image_bytes(CTextCanvasImageOptions {
content: "Hi".to_string(),
font: Font::Tss16,
rotation: Rotation::Rotation0,
bold: None,
alpha: 255,
})
.unwrap();
assert!(image.starts_with(&[0x89, b'P', b'N', b'G']));
let mut command = BaseCpcl::new(common::lifecycle());
command.text_canvas((1, 2, image)).unwrap();
assert!(command_binary(&mut command).starts_with(b"CG "));
}
#[test]
fn test_image_uses_custom_gray_threshold() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.image(CImagePixels::new(CImagePixelsOptions {
x: 0,
y: 0,
pixels: vec![150, 150, 150, 255],
width: 1,
height: 1,
compress: false,
reverse: false,
gray_threshold: Some(100),
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
}))
.unwrap();
assert_eq!(command_binary(&mut command), b"CG 1 1 0 0 \x00\r\n\r\n");
}
#[test]
fn test_image_supports_dart_reverse_arg() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.image(CImagePixels::new(CImagePixelsOptions {
x: 0,
y: 0,
pixels: vec![0, 0, 0, 255],
width: 1,
height: 1,
compress: false,
reverse: true,
gray_threshold: Some(128),
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
}))
.unwrap();
assert_eq!(command_binary(&mut command), b"CG 1 1 0 0 \x00\r\n\r\n");
}
#[test]
fn test_image_supports_dart_smooth_and_edge_dither_args() {
let mut command = BaseCpcl::new(common::lifecycle());
command
.image(CImagePixels::new(CImagePixelsOptions {
x: 0,
y: 0,
pixels: vec![
120, 120, 120, 255, 120, 120, 120, 255, 120, 120, 120, 255, 255, 255, 255, 255,
],
width: 4,
height: 1,
compress: false,
reverse: false,
gray_threshold: Some(128),
smooth_weight: 0,
edge_dither_mode: Some(ThresholdEdgeDitherMode::Floyd),
edge_dither_depth: ThresholdEdgeDitherDepth::Deep,
}))
.unwrap();
assert_eq!(command_binary(&mut command), b"CG 1 1 0 0 \xa0\r\n\r\n");
}