diff --git a/src/common/cpp_essentials/base_extentions/qr_ec_level.rs b/src/common/cpp_essentials/base_extentions/qr_ec_level.rs index 365c7d3..ee582da 100644 --- a/src/common/cpp_essentials/base_extentions/qr_ec_level.rs +++ b/src/common/cpp_essentials/base_extentions/qr_ec_level.rs @@ -2,7 +2,7 @@ use crate::common::Result; use crate::qrcode::decoder::ErrorCorrectionLevel; impl ErrorCorrectionLevel { - pub fn ECLevelFromBits(bits: u8, isMicro: bool) -> Self { + pub fn ECLevelFromBitsSigned(bits: i8, isMicro: bool) -> Self { if (isMicro) { let LEVEL_FOR_BITS: [ErrorCorrectionLevel; 8] = [ ErrorCorrectionLevel::L, @@ -24,4 +24,8 @@ impl ErrorCorrectionLevel { ]; return LEVEL_FOR_BITS[bits as usize & 0x3]; } + + pub fn ECLevelFromBits(bits: u8, isMicro: bool) -> Self { + Self::ECLevelFromBitsSigned(bits as i8, isMicro) + } } diff --git a/src/common/cpp_essentials/base_extentions/qr_formatinformation.rs b/src/common/cpp_essentials/base_extentions/qr_formatinformation.rs index 90b89de..b021306 100644 --- a/src/common/cpp_essentials/base_extentions/qr_formatinformation.rs +++ b/src/common/cpp_essentials/base_extentions/qr_formatinformation.rs @@ -125,4 +125,9 @@ impl FormatInformation { pub fn isValid(&self) -> bool { self.hammingDistance <= 3 } + + pub fn cpp_eq(&self, other: &Self) -> bool { + self.data_mask == other.data_mask + && self.error_correction_level == other.error_correction_level + } } diff --git a/src/common/cpp_essentials/decoder_result.rs b/src/common/cpp_essentials/decoder_result.rs index d8a9ab5..52862a0 100644 --- a/src/common/cpp_essentials/decoder_result.rs +++ b/src/common/cpp_essentials/decoder_result.rs @@ -200,3 +200,32 @@ where // } } + +impl DecoderResult +where + T: Copy + Clone + Default + Eq + PartialEq, +{ + pub fn text(&self) -> String { + self.content.to_string() + } + + pub fn symbologyIdentifier(&self) -> String { + let s = self.content.symbology; + if s.code > 0 { + format!( + "]{}{}", + vec!['1'; s.code as usize].into_iter().collect::(), + char::from( + s.modifier + + if self.content.is_eci { + s.eciModifierOffset + } else { + 0 + } + ) + ) + } else { + String::default() + } + } +} diff --git a/src/common/eci_string_builder.rs b/src/common/eci_string_builder.rs index 72bfa6a..b791d61 100644 --- a/src/common/eci_string_builder.rs +++ b/src/common/eci_string_builder.rs @@ -32,7 +32,7 @@ use super::{CharacterSet, Eci}; */ #[derive(Default, PartialEq, Eq, Debug, Clone)] pub struct ECIStringBuilder { - is_eci: bool, + pub is_eci: bool, eci_result: Option, bytes: Vec, eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end) diff --git a/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.cpp b/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.cpp deleted file mode 100644 index 66d4f89..0000000 --- a/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -* Copyright 2017 Huy Cuong Nguyen -* Copyright 2008 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -#include "BitArray.h" -#include "ByteArray.h" -#include "DecoderResult.h" -#include "qrcode/QRDataMask.h" -#include "qrcode/QRDecoder.h" -#include "qrcode/QRErrorCorrectionLevel.h" -#include "qrcode/QRVersion.h" - -#include "gtest/gtest.h" - -namespace ZXing { - namespace QRCode { - DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel); - } -} - -using namespace ZXing; -using namespace ZXing::QRCode; - -TEST(QRDecodedBitStreamParserTest, SimpleByteMode) -{ - BitArray ba; - ba.appendBits(0x04, 4); // Byte mode - ba.appendBits(0x03, 8); // 3 bytes - ba.appendBits(0xF1, 8); - ba.appendBits(0xF2, 8); - ba.appendBits(0xF3, 8); - auto result = DecodeBitStream(ba.toBytes(), *Version::FromNumber(1), ErrorCorrectionLevel::Medium).text(); - EXPECT_EQ(L"\xF1\xF2\xF3", result); -} - -TEST(QRDecodedBitStreamParserTest, SimpleSJIS) -{ - BitArray ba; - ba.appendBits(0x04, 4); // Byte mode - ba.appendBits(0x04, 8); // 4 bytes - ba.appendBits(0xA1, 8); - ba.appendBits(0xA2, 8); - ba.appendBits(0xA3, 8); - ba.appendBits(0xD0, 8); - auto result = DecodeBitStream(ba.toBytes(), *Version::FromNumber(1), ErrorCorrectionLevel::Medium).text(); - EXPECT_EQ(L"\uff61\uff62\uff63\uff90", result); -} - -TEST(QRDecodedBitStreamParserTest, ECI) -{ - BitArray ba; - ba.appendBits(0x07, 4); // ECI mode - ba.appendBits(0x02, 8); // ECI 2 = CP437 encoding - ba.appendBits(0x04, 4); // Byte mode - ba.appendBits(0x03, 8); // 3 bytes - ba.appendBits(0xA1, 8); - ba.appendBits(0xA2, 8); - ba.appendBits(0xA3, 8); - auto result = DecodeBitStream(ba.toBytes(), *Version::FromNumber(1), ErrorCorrectionLevel::Medium).text(); - EXPECT_EQ(L"\xED\xF3\xFA", result); -} - -TEST(QRDecodedBitStreamParserTest, Hanzi) -{ - BitArray ba; - ba.appendBits(0x0D, 4); // Hanzi mode - ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding - ba.appendBits(0x01, 8); // 1 characters - ba.appendBits(0x03C1, 13); - auto result = DecodeBitStream(ba.toBytes(), *Version::FromNumber(1), ErrorCorrectionLevel::Medium).text(); - EXPECT_EQ(L"\u963f", result); -} - -TEST(QRDecodedBitStreamParserTest, HanziLevel1) -{ - BitArray ba; - ba.appendBits(0x0D, 4); // Hanzi mode - ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding - ba.appendBits(0x01, 8); // 1 characters - // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 - ba.appendBits(0x0181, 13); - - auto result = DecodeBitStream(ba.toBytes(), *Version::FromNumber(1), ErrorCorrectionLevel::Medium).text(); - EXPECT_EQ(L"\u30a2", result); -} - -TEST(QRDecodedBitStreamParserTest, SymbologyIdentifier) -{ - const Version& version = *Version::FromNumber(1); - const ErrorCorrectionLevel ecLevel = ErrorCorrectionLevel::Medium; - DecoderResult result; - - // Plain "ANUM(1) A" - result = DecodeBitStream({0x20, 0x09, 0x40}, version, ecLevel); - EXPECT_EQ(result.symbologyIdentifier(), "]Q1"); - EXPECT_EQ(result.text(), L"A"); - - // GS1 "FNC1(1st) NUM(4) 2001" - result = DecodeBitStream({0x51, 0x01, 0x0C, 0x81, 0x00}, version, ecLevel); - EXPECT_EQ(result.symbologyIdentifier(), "]Q3"); - EXPECT_EQ(result.text(), L"2001"); // "(20)01" - - // GS1 "NUM(4) 2001 FNC1(1st) 301" - FNC1(1st) can occur anywhere (this actually violates the specification) - result = DecodeBitStream({0x10, 0x10, 0xC8, 0x15, 0x10, 0x0D, 0x2D, 0x00}, version, ecLevel); - EXPECT_EQ(result.symbologyIdentifier(), "]Q3"); - EXPECT_EQ(result.text(), L"2001301"); // "(20)01(30)1" - - // AIM "FNC1(2nd) 99 (0x63) ANUM(1) A" - result = DecodeBitStream({0x96, 0x32, 0x00, 0x94, 0x00}, version, ecLevel); - EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); - EXPECT_EQ(result.text(), L"99A"); - - // AIM "BYTE(1) A FNC1(2nd) 99 (0x63) BYTE(1) B" - FNC1(2nd) can occur anywhere - // Disabled this test, since this violates the specification and the code does support it anymore -// result = DecodeBitStream({0x40, 0x14, 0x19, 0x63, 0x40, 0x14, 0x20, 0x00}, version, ecLevel, ""); -// EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); -// EXPECT_EQ(result.text(), L"99AB"); // Application Indicator prefixed to data - - // AIM "FNC1(2nd) A (100 + 61 = 0xA5) ANUM(1) B" - result = DecodeBitStream({0x9A, 0x52, 0x00, 0x96, 0x00}, version, ecLevel); - EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); - EXPECT_EQ(result.text(), L"AB"); - - // AIM "FNC1(2nd) a (100 + 97 = 0xC5) ANUM(1) B" - result = DecodeBitStream({0x9C, 0x52, 0x00, 0x96, 0x00}, version, ecLevel); - EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); - EXPECT_EQ(result.text(), L"aB"); - - // Bad AIM Application Indicator "FNC1(2nd) @ (0xA4) ANUM(1) B" - result = DecodeBitStream({0x9A, 0x42, 0x00, 0x96, 0x00}, version, ecLevel); - EXPECT_FALSE(result.isValid()); -} diff --git a/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs b/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs new file mode 100644 index 0000000..c00b897 --- /dev/null +++ b/src/qrcode/cpp_port/test/QRDecodedBitStreamParserTest.rs @@ -0,0 +1,190 @@ +/* +* Copyright 2017 Huy Cuong Nguyen +* Copyright 2008 ZXing authors +*/ +// SPDX-License-Identifier: Apache-2.0 + +// #include "BitArray.h" +// #include "ByteArray.h" +// #include "DecoderResult.h" +// #include "qrcode/QRDataMask.h" +// #include "qrcode/QRDecoder.h" +// #include "qrcode/QRErrorCorrectionLevel.h" +// #include "qrcode/QRVersion.h" + +// #include "gtest/gtest.h" + +// namespace ZXing { +// namespace QRCode { +// DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel); +// } +// } + +// using namespace ZXing; +// using namespace ZXing::QRCode; + +use crate::common::Result; + +use crate::{ + common::{cpp_essentials::DecoderResult, BitArray}, + qrcode::{ + cpp_port::decoder::DecodeBitStream, + decoder::{ErrorCorrectionLevel, Version}, + }, +}; + +#[test] +fn SimpleByteMode() { + let mut ba = BitArray::new(); + ba.appendBits(0x04, 4); // Byte mode + ba.appendBits(0x03, 8); // 3 bytes + ba.appendBits(0xF1, 8); + ba.appendBits(0xF2, 8); + ba.appendBits(0xF3, 8); + let bytes: Vec = ba.into(); + let result = DecodeBitStream( + &bytes, + Version::FromNumber(1, false).expect("find_version"), + ErrorCorrectionLevel::M, + ) + .expect("Decode") + .content() + .to_string(); + let str = String::from_utf16(&[0xF1, 0xF2, 0xF3]).unwrap(); + assert_eq!(str, result); +} + +#[test] +fn SimpleSJIS() { + let mut ba = BitArray::new(); + ba.appendBits(0x04, 4); // Byte mode + ba.appendBits(0x04, 8); // 4 bytes + ba.appendBits(0xA1, 8); + ba.appendBits(0xA2, 8); + ba.appendBits(0xA3, 8); + ba.appendBits(0xD0, 8); + let bytes: Vec = ba.into(); + let result = DecodeBitStream( + &bytes, + Version::FromNumber(1, false).unwrap(), + ErrorCorrectionLevel::M, + ) + .unwrap() + .content() + .to_string(); + assert_eq!("\u{ff61}\u{ff62}\u{ff63}\u{ff90}", result); +} + +#[test] +fn ECI() { + let mut ba = BitArray::new(); + ba.appendBits(0x07, 4); // ECI mode + ba.appendBits(0x02, 8); // ECI 2 = CP437 encoding + ba.appendBits(0x04, 4); // Byte mode + ba.appendBits(0x03, 8); // 3 bytes + ba.appendBits(0xA1, 8); + ba.appendBits(0xA2, 8); + ba.appendBits(0xA3, 8); + let bytes: Vec = ba.into(); + let result = DecodeBitStream( + &bytes, + Version::FromNumber(1, false).unwrap(), + ErrorCorrectionLevel::M, + ) + .unwrap() + .content() + .to_string(); + assert_eq!("\u{ED}\u{F3}\u{FA}", result); +} + +#[test] +fn Hanzi() { + let mut ba = BitArray::new(); + ba.appendBits(0x0D, 4); // Hanzi mode + ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding + ba.appendBits(0x01, 8); // 1 characters + ba.appendBits(0x03C1, 13); + let bytes: Vec = ba.into(); + let result = DecodeBitStream( + &bytes, + Version::FromNumber(1, false).unwrap(), + ErrorCorrectionLevel::M, + ) + .unwrap() + .content() + .to_string(); + assert_eq!("\u{963f}", result); +} + +#[test] +fn HanziLevel1() { + let mut ba = BitArray::new(); + ba.appendBits(0x0D, 4); // Hanzi mode + ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding + ba.appendBits(0x01, 8); // 1 characters + // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 + ba.appendBits(0x0181, 13); + + let bytes: Vec = ba.into(); + + let result = DecodeBitStream( + &bytes, + Version::FromNumber(1, false).unwrap(), + ErrorCorrectionLevel::M, + ) + .unwrap() + .content() + .to_string(); + assert_eq!("\u{30a2}", result); +} + +#[test] +fn SymbologyIdentifier() { + let version = Version::FromNumber(1, false).unwrap(); + let ecLevel = ErrorCorrectionLevel::M; + + // Plain "ANUM(1) A" + let result = DecodeBitStream(&[0x20, 0x09, 0x40], version, ecLevel).unwrap(); + assert_eq!(result.symbologyIdentifier(), "]Q1"); + assert_eq!(result.text(), "A"); + + // GS1 "FNC1(1st) NUM(4) 2001" + let result = DecodeBitStream(&[0x51, 0x01, 0x0C, 0x81, 0x00], version, ecLevel).unwrap(); + assert_eq!(result.symbologyIdentifier(), "]Q3"); + assert_eq!(result.text(), "2001"); // "(20)01" + + // GS1 "NUM(4) 2001 FNC1(1st) 301" - FNC1(1st) can occur anywhere (this actually violates the specification) + let result = DecodeBitStream( + &[0x10, 0x10, 0xC8, 0x15, 0x10, 0x0D, 0x2D, 0x00], + version, + ecLevel, + ) + .unwrap(); + assert_eq!(result.symbologyIdentifier(), "]Q3"); + assert_eq!(result.text(), "2001301"); // "(20)01(30)1" + + // AIM "FNC1(2nd) 99 (0x63) ANUM(1) A" + let result = DecodeBitStream(&[0x96, 0x32, 0x00, 0x94, 0x00], version, ecLevel).unwrap(); + assert_eq!(result.symbologyIdentifier(), "]Q5"); + assert_eq!(result.text(), "99A"); + + // AIM "BYTE(1) A FNC1(2nd) 99 (0x63) BYTE(1) B" - FNC1(2nd) can occur anywhere + // Disabled this test, since this violates the specification and the code does support it anymore + // result = DecodeBitStream({0x40, 0x14, 0x19, 0x63, 0x40, 0x14, 0x20, 0x00}, version, ecLevel, ""); + // assert_eq!(result.symbologyIdentifier(), "]Q5"); + // assert_eq!(result.text(), L"99AB"); // Application Indicator prefixed to data + + // AIM "FNC1(2nd) A (100 + 61 = 0xA5) ANUM(1) B" + let result = DecodeBitStream(&[0x9A, 0x52, 0x00, 0x96, 0x00], version, ecLevel).unwrap(); + assert_eq!(result.symbologyIdentifier(), "]Q5"); + assert_eq!(result.text(), "AB"); + + // AIM "FNC1(2nd) a (100 + 97 = 0xC5) ANUM(1) B" + let result = DecodeBitStream(&[0x9C, 0x52, 0x00, 0x96, 0x00], version, ecLevel).unwrap(); + assert_eq!(result.symbologyIdentifier(), "]Q5"); + assert_eq!(result.text(), "aB"); + + // Bad AIM Application Indicator "FNC1(2nd) @ (0xA4) ANUM(1) B" + let result = DecodeBitStream(&[0x9A, 0x42, 0x00, 0x96, 0x00], version, ecLevel).unwrap(); + assert!(!result.isValid()); +} diff --git a/src/qrcode/cpp_port/test/QRErrorCorrectionLevelTest.cpp b/src/qrcode/cpp_port/test/QRErrorCorrectionLevelTest.cpp deleted file mode 100644 index 77c1030..0000000 --- a/src/qrcode/cpp_port/test/QRErrorCorrectionLevelTest.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* -* Copyright 2017 Huy Cuong Nguyen -* Copyright 2008 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -#include "qrcode/QRErrorCorrectionLevel.h" - -#include "gtest/gtest.h" - -using namespace ZXing; -using namespace ZXing::QRCode; - -TEST(QRErrorCorrectionLevelTest, ForBits) -{ - EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(0)); - EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(1)); - EXPECT_EQ(ErrorCorrectionLevel::High, ECLevelFromBits(2)); - EXPECT_EQ(ErrorCorrectionLevel::Quality, ECLevelFromBits(3)); -} - -TEST(QRErrorCorrectionLevelTest, ForMicroBits) -{ - EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(0, true)); - EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(1, true)); - EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(2, true)); - EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(3, true)); - EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(4, true)); - EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(5, true)); - EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(6, true)); - EXPECT_EQ(ErrorCorrectionLevel::Quality, ECLevelFromBits(7, true)); - - EXPECT_EQ(ErrorCorrectionLevel::Quality, ECLevelFromBits(-1, true)); - EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(8, true)); -} - -TEST(QRErrorCorrectionLevelTest, ToString) -{ - using namespace std::literals; - - EXPECT_EQ("L"s, ToString(ErrorCorrectionLevel::Low)); - EXPECT_EQ("M"s, ToString(ErrorCorrectionLevel::Medium)); - EXPECT_EQ("Q"s, ToString(ErrorCorrectionLevel::Quality)); - EXPECT_EQ("H"s, ToString(ErrorCorrectionLevel::High)); -} diff --git a/src/qrcode/cpp_port/test/QRErrorCorrectionLevelTest.rs b/src/qrcode/cpp_port/test/QRErrorCorrectionLevelTest.rs new file mode 100644 index 0000000..a8eb509 --- /dev/null +++ b/src/qrcode/cpp_port/test/QRErrorCorrectionLevelTest.rs @@ -0,0 +1,89 @@ +/* +* Copyright 2017 Huy Cuong Nguyen +* Copyright 2008 ZXing authors +*/ +// SPDX-License-Identifier: Apache-2.0 + +// #include "qrcode/QRErrorCorrectionLevel.h" + +// #include "gtest/gtest.h" + +// using namespace ZXing; +// using namespace ZXing::QRCode; + +use crate::qrcode::decoder::ErrorCorrectionLevel; + +#[test] +fn ForBits() { + assert_eq!( + ErrorCorrectionLevel::M, + ErrorCorrectionLevel::ECLevelFromBits(0, false) + ); + assert_eq!( + ErrorCorrectionLevel::L, + ErrorCorrectionLevel::ECLevelFromBits(1, false) + ); + assert_eq!( + ErrorCorrectionLevel::H, + ErrorCorrectionLevel::ECLevelFromBits(2, false) + ); + assert_eq!( + ErrorCorrectionLevel::Q, + ErrorCorrectionLevel::ECLevelFromBits(3, false) + ); +} + +#[test] +fn ForMicroBits() { + assert_eq!( + ErrorCorrectionLevel::L, + ErrorCorrectionLevel::ECLevelFromBits(0, true) + ); + assert_eq!( + ErrorCorrectionLevel::L, + ErrorCorrectionLevel::ECLevelFromBits(1, true) + ); + assert_eq!( + ErrorCorrectionLevel::M, + ErrorCorrectionLevel::ECLevelFromBits(2, true) + ); + assert_eq!( + ErrorCorrectionLevel::L, + ErrorCorrectionLevel::ECLevelFromBits(3, true) + ); + assert_eq!( + ErrorCorrectionLevel::M, + ErrorCorrectionLevel::ECLevelFromBits(4, true) + ); + assert_eq!( + ErrorCorrectionLevel::L, + ErrorCorrectionLevel::ECLevelFromBits(5, true) + ); + assert_eq!( + ErrorCorrectionLevel::M, + ErrorCorrectionLevel::ECLevelFromBits(6, true) + ); + assert_eq!( + ErrorCorrectionLevel::Q, + ErrorCorrectionLevel::ECLevelFromBits(7, true) + ); + + assert_eq!( + ErrorCorrectionLevel::Q, + ErrorCorrectionLevel::ECLevelFromBitsSigned(-1, true) + ); + assert_eq!( + ErrorCorrectionLevel::L, + ErrorCorrectionLevel::ECLevelFromBits(8, true) + ); +} + +#[test] +fn ToString() { + // using namespace std::literals; + + assert_eq!("L", ErrorCorrectionLevel::L.to_string()); + assert_eq!("M", ErrorCorrectionLevel::M.to_string()); + assert_eq!("Q", ErrorCorrectionLevel::Q.to_string()); + assert_eq!("H", ErrorCorrectionLevel::H.to_string()); +} diff --git a/src/qrcode/cpp_port/test/QRFormatInformationTest.rs b/src/qrcode/cpp_port/test/QRFormatInformationTest.rs index 0d2a867..67f326a 100644 --- a/src/qrcode/cpp_port/test/QRFormatInformationTest.rs +++ b/src/qrcode/cpp_port/test/QRFormatInformationTest.rs @@ -28,36 +28,40 @@ fn Decode() { assert_eq!(0x07, expected.data_mask); assert_eq!(ErrorCorrectionLevel::Q, expected.error_correction_level); // where the code forgot the mask! - assert_eq!( - expected, - FormatInformation::DecodeQR(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO2) - ); + // assert_eq!( + // expected, + // FormatInformation::DecodeQR(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO2) + // ); + cpp_eq( + &expected, + &FormatInformation::DecodeQR(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO2), + ) } #[test] fn DecodeWithBitDifference() { let expected = FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO2); // 1,2,3,4 bits difference - assert_eq!( - expected, - FormatInformation::DecodeQR( + cpp_eq( + &expected, + &FormatInformation::DecodeQR( MASKED_TEST_FORMAT_INFO ^ 0x01, - MASKED_TEST_FORMAT_INFO2 ^ 0x01 - ) + MASKED_TEST_FORMAT_INFO2 ^ 0x01, + ), ); - assert_eq!( - expected, - FormatInformation::DecodeQR( + cpp_eq( + &expected, + &FormatInformation::DecodeQR( MASKED_TEST_FORMAT_INFO ^ 0x03, - MASKED_TEST_FORMAT_INFO2 ^ 0x03 - ) + MASKED_TEST_FORMAT_INFO2 ^ 0x03, + ), ); - assert_eq!( - expected, - FormatInformation::DecodeQR( + cpp_eq( + &expected, + &FormatInformation::DecodeQR( MASKED_TEST_FORMAT_INFO ^ 0x07, - MASKED_TEST_FORMAT_INFO2 ^ 0x07 - ) + MASKED_TEST_FORMAT_INFO2 ^ 0x07, + ), ); assert!(!FormatInformation::DecodeQR( MASKED_TEST_FORMAT_INFO ^ 0x0F, @@ -69,12 +73,12 @@ fn DecodeWithBitDifference() { #[test] fn DecodeWithMisread() { let expected = FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO2); - assert_eq!( - expected, - FormatInformation::DecodeQR( + cpp_eq( + &expected, + &FormatInformation::DecodeQR( MASKED_TEST_FORMAT_INFO ^ 0x03, - MASKED_TEST_FORMAT_INFO2 ^ 0x0F - ) + MASKED_TEST_FORMAT_INFO2 ^ 0x0F, + ), ); } @@ -102,17 +106,17 @@ fn DecodeMicroWithBitDifference() { let expected = FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO); // 1,2,3 bits difference - assert_eq!( - expected, - FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x01) + cpp_eq( + &expected, + &FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x01), ); - assert_eq!( - expected, - FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x03) + cpp_eq( + &expected, + &FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x03), ); - assert_eq!( - expected, - FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x07) + cpp_eq( + &expected, + &FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x07), ); // Bigger bit differences can return valid FormatInformation objects but the data mask and error @@ -122,3 +126,7 @@ fn DecodeMicroWithBitDifference() { // EXPECT_NE(expected.errorCorrectionLevel(), // FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x3f).errorCorrectionLevel()); } + +fn cpp_eq(rhs: &FormatInformation, lhs: &FormatInformation) { + assert!(rhs.cpp_eq(lhs)) +} diff --git a/src/qrcode/cpp_port/test/mod.rs b/src/qrcode/cpp_port/test/mod.rs index 4aaae93..9383384 100644 --- a/src/qrcode/cpp_port/test/mod.rs +++ b/src/qrcode/cpp_port/test/mod.rs @@ -2,3 +2,7 @@ mod QRModeTest; mod QRVersionTest; mod QRFormatInformationTest; + +mod QRErrorCorrectionLevelTest; + +mod QRDecodedBitStreamParserTest;