From 1e8f949035f351b88a580b165881666bd9686083 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Mon, 12 Dec 2022 18:36:22 -0600 Subject: [PATCH] code 128 writer tests pass --- src/oned/Code128WriterTestCase.java | 359 ------------------ src/oned/code_128_reader.rs | 6 + src/oned/code_128_writer.rs | 36 +- src/oned/code_128_writer_test_tase.rs | 502 ++++++++++++++++++++++++++ src/oned/mod.rs | 3 + 5 files changed, 535 insertions(+), 371 deletions(-) delete mode 100644 src/oned/Code128WriterTestCase.java create mode 100644 src/oned/code_128_writer_test_tase.rs diff --git a/src/oned/Code128WriterTestCase.java b/src/oned/Code128WriterTestCase.java deleted file mode 100644 index fa1433d..0000000 --- a/src/oned/Code128WriterTestCase.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2014 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.zxing.oned; - -import com.google.zxing.common.BitMatrixTestCase; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.EncodeHintType; -import com.google.zxing.RXingResult; -import com.google.zxing.Writer; -import com.google.zxing.common.BitArray; -import com.google.zxing.common.BitMatrix; - -import java.util.Map; -import java.util.EnumMap; - -/** - * Tests {@link Code128Writer}. - */ -public class Code128WriterTestCase extends Assert { - - private static final String FNC1 = "11110101110"; - private static final String FNC2 = "11110101000"; - private static final String FNC3 = "10111100010"; - private static final String FNC4A = "11101011110"; - private static final String FNC4B = "10111101110"; - private static final String START_CODE_A = "11010000100"; - private static final String START_CODE_B = "11010010000"; - private static final String START_CODE_C = "11010011100"; - private static final String SWITCH_CODE_A = "11101011110"; - private static final String SWITCH_CODE_B = "10111101110"; - private static final String QUIET_SPACE = "00000"; - private static final String STOP = "1100011101011"; - private static final String LF = "10000110010"; - - private Writer writer; - private Code128Reader reader; - - @Before - public void setUp() { - writer = new Code128Writer(); - reader = new Code128Reader(); - } - - @Test - public void testEncodeWithFunc3() throws Exception { - String toEncode = "\u00f3" + "123"; - String expected = QUIET_SPACE + START_CODE_B + FNC3 + - // "1" "2" "3" check digit 51 - "10011100110" + "11001110010" + "11001011100" + "11101000110" + STOP + QUIET_SPACE; - - BitMatrix result = encode(toEncode, false, "123"); - - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(expected, actual); - - int width = result.getWidth(); - result = encode(toEncode, true, "123"); - - assertEquals(width, result.getWidth()); - } - - @Test - public void testEncodeWithFunc2() throws Exception { - String toEncode = "\u00f2" + "123"; - String expected = QUIET_SPACE + START_CODE_B + FNC2 + - // "1" "2" "3" check digit 56 - "10011100110" + "11001110010" + "11001011100" + "11100010110" + STOP + QUIET_SPACE; - - BitMatrix result = encode(toEncode, false, "123"); - - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(expected, actual); - - int width = result.getWidth(); - result = encode(toEncode, true, "123"); - - assertEquals(width, result.getWidth()); - } - - @Test - public void testEncodeWithFunc1() throws Exception { - String toEncode = "\u00f1" + "123"; - String expected = QUIET_SPACE + START_CODE_C + FNC1 + - // "12" "3" check digit 92 - "10110011100" + SWITCH_CODE_B + "11001011100" + "10101111000" + STOP + QUIET_SPACE; - - BitMatrix result = encode(toEncode, false, "123"); - - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(expected, actual); - - int width = result.getWidth(); - result = encode(toEncode, true, "123"); - - assertEquals(width, result.getWidth()); - } - - @Test - public void testRoundtrip() throws Exception { - String toEncode = "\u00f1" + "10958" + "\u00f1" + "17160526"; - String expected = "1095817160526"; - - BitMatrix encRXingResult = encode(toEncode, false, expected); - - int width = encRXingResult.getWidth(); - encRXingResult = encode(toEncode, true, expected); - //Compact encoding has one latch less and encodes as STARTA,FNC1,1,CODEC,09,58,FNC1,17,16,05,26 - assertEquals(width, encRXingResult.getWidth() + 11); - } - - @Test - public void testLongCompact() throws Exception { - //test longest possible input - String toEncode = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - encode(toEncode, true, toEncode); - } - - @Test - public void testShift() throws Exception { - //compare fast to compact - String toEncode = "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"; - BitMatrix result = encode(toEncode, false, toEncode); - - int width = result.getWidth(); - result = encode(toEncode, true, toEncode); - - //big difference since the fast algoritm doesn't make use of SHIFT - assertEquals(width, result.getWidth() + 253); - } - - @Test - public void testDigitMixCompaction() throws Exception { - //compare fast to compact - String toEncode = "A1A12A123A1234A12345AA1AA12AA123AA1234AA1235"; - BitMatrix result = encode(toEncode, false, toEncode); - - int width = result.getWidth(); - result = encode(toEncode, true, toEncode); - - //very good, no difference - assertEquals(width, result.getWidth()); - } - - @Test - public void testCompaction1() throws Exception { - //compare fast to compact - String toEncode = "AAAAAAAAAAA12AAAAAAAAA"; - BitMatrix result = encode(toEncode, false, toEncode); - - int width = result.getWidth(); - result = encode(toEncode, true, toEncode); - - //very good, no difference - assertEquals(width, result.getWidth()); - } - - @Test - public void testCompaction2() throws Exception { - //compare fast to compact - String toEncode = "AAAAAAAAAAA1212aaaaaaaaa"; - BitMatrix result = encode(toEncode, false, toEncode); - - int width = result.getWidth(); - result = encode(toEncode, true, toEncode); - - //very good, no difference - assertEquals(width, result.getWidth()); - } - - @Test - public void testEncodeWithFunc4() throws Exception { - String toEncode = "\u00f4" + "123"; - String expected = QUIET_SPACE + START_CODE_B + FNC4B + - // "1" "2" "3" check digit 59 - "10011100110" + "11001110010" + "11001011100" + "11100011010" + STOP + QUIET_SPACE; - - BitMatrix result = encode(toEncode, false, null); - - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(expected, actual); - - int width = result.getWidth(); - result = encode(toEncode, true, null); - assertEquals(width, result.getWidth()); - } - - @Test - public void testEncodeWithFncsAndNumberInCodesetA() throws Exception { - String toEncode = "\n" + "\u00f1" + "\u00f4" + "1" + "\n"; - - String expected = QUIET_SPACE + START_CODE_A + LF + FNC1 + FNC4A + - "10011100110" + LF + "10101111000" + STOP + QUIET_SPACE; - - BitMatrix result = encode(toEncode, false, null); - - String actual = BitMatrixTestCase.matrixToString(result); - - assertEquals(expected, actual); - - int width = result.getWidth(); - result = encode(toEncode, true, null); - assertEquals(width, result.getWidth()); - } - - @Test - public void testEncodeSwitchBetweenCodesetsAAndB() throws Exception { - // start with A switch to B and back to A - testEncode("\0ABab\u0010", QUIET_SPACE + START_CODE_A + - // "\0" "A" "B" Switch to B "a" "b" - "10100001100" + "10100011000" + "10001011000" + SWITCH_CODE_B + "10010110000" + "10010000110" + - // Switch to A "\u0010" check digit - SWITCH_CODE_A + "10100111100" + "11001110100" + STOP + QUIET_SPACE); - - // start with B switch to A and back to B - // the compact encoder encodes this shorter as STARTB,a,b,SHIFT,NUL,a,b - testEncode("ab\0ab", QUIET_SPACE + START_CODE_B + - // "a" "b" Switch to A "\0" Switch to B - "10010110000" + "10010000110" + SWITCH_CODE_A + "10100001100" + SWITCH_CODE_B + - // "a" "b" check digit - "10010110000" + "10010000110" + "11010001110" + STOP + QUIET_SPACE); - } - - private void testEncode(String toEncode, String expected) throws Exception { - BitMatrix result = encode(toEncode, false, toEncode); - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(toEncode, expected, actual); - - - int width = result.getWidth(); - result = encode(toEncode, true, toEncode); - assertTrue(result.getWidth() <= width); - - } - - @Test(expected = IllegalArgumentException.class) - public void testEncodeWithForcedCodeSetFailureCodeSetABadCharacter() throws Exception { - // Lower case characters should not be accepted when the code set is forced to A. - String toEncode = "ASDFx0123"; - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "A"); - writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - } - - @Test(expected = IllegalArgumentException.class) - public void testEncodeWithForcedCodeSetFailureCodeSetBBadCharacter() throws Exception { - String toEncode = "ASdf\00123"; // \0 (ascii value 0) - // Characters with ASCII value below 32 should not be accepted when the code set is forced to B. - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "B"); - writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - } - - @Test(expected = IllegalArgumentException.class) - public void testEncodeWithForcedCodeSetFailureCodeSetCBadCharactersNonNum() throws Exception { - String toEncode = "123a5678"; - // Non-digit characters should not be accepted when the code set is forced to C. - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "C"); - writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - } - - @Test(expected = IllegalArgumentException.class) - public void testEncodeWithForcedCodeSetFailureCodeSetCBadCharactersFncCode() throws Exception { - String toEncode = "123\u00f2a678"; - // Function codes other than 1 should not be accepted when the code set is forced to C. - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "C"); - writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - } - - @Test(expected = IllegalArgumentException.class) - public void testEncodeWithForcedCodeSetFailureCodeSetCWrongAmountOfDigits() throws Exception { - String toEncode = "123456789"; - // An uneven amount of digits should not be accepted when the code set is forced to C. - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "C"); - writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - } - - @Test - public void testEncodeWithForcedCodeSetFailureCodeSetA() throws Exception { - String toEncode = "AB123"; - // would default to B "A" "B" "1" - String expected = QUIET_SPACE + START_CODE_A + "10100011000" + "10001011000" + "10011100110" + - // "2" "3" check digit 10 - "11001110010" + "11001011100" + "11001000100" + STOP + QUIET_SPACE; - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "A"); - BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(expected, actual); - } - - @Test - public void testEncodeWithForcedCodeSetFailureCodeSetB() throws Exception { - String toEncode = "1234"; - // would default to C "1" "2" "3" - String expected = QUIET_SPACE + START_CODE_B + "10011100110" + "11001110010" + "11001011100" + - // "4" check digit 88 - "11001001110" + "11110010010" + STOP + QUIET_SPACE; - - Map hints = new EnumMap<>(EncodeHintType.class); - hints.put(EncodeHintType.FORCE_CODE_SET, "B"); - BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - - String actual = BitMatrixTestCase.matrixToString(result); - assertEquals(expected, actual); - } - - private BitMatrix encode(String toEncode, boolean compact, String expectedLoopback) throws Exception { - Map hints = new EnumMap<>(EncodeHintType.class); - if (compact) { - hints.put(EncodeHintType.CODE128_COMPACT, Boolean.TRUE); - } - BitMatrix encRXingResult = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); - if (expectedLoopback != null) { - BitArray row = encRXingResult.getRow(0, null); - RXingResult rtRXingResult = reader.decodeRow(0, row, null); - String actual = rtRXingResult.getText(); - assertEquals(expectedLoopback, actual); - } - if (compact) { - //check that what is encoded compactly yields the same on loopback as what was encoded fast. - BitArray row = encRXingResult.getRow(0, null); - RXingResult rtRXingResult = reader.decodeRow(0, row, null); - String actual = rtRXingResult.getText(); - BitMatrix encRXingResultFast = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0); - row = encRXingResultFast.getRow(0, null); - rtRXingResult = reader.decodeRow(0, row, null); - assertEquals(rtRXingResult.getText(), actual); - } - return encRXingResult; - } -} diff --git a/src/oned/code_128_reader.rs b/src/oned/code_128_reader.rs index 481716d..7343343 100644 --- a/src/oned/code_128_reader.rs +++ b/src/oned/code_128_reader.rs @@ -449,6 +449,12 @@ impl Code128Reader { } } +impl Default for Code128Reader { + fn default() -> Self { + Self {} + } +} + use lazy_static::lazy_static; lazy_static! { diff --git a/src/oned/code_128_writer.rs b/src/oned/code_128_writer.rs index 50d500b..8b625d2 100644 --- a/src/oned/code_128_writer.rs +++ b/src/oned/code_128_writer.rs @@ -246,8 +246,14 @@ fn encodeFast(contents: &str, forcedCodeSet: i32) -> Result, Exception "Bad number of characters for digit only encoding.".to_owned(), )); } - patternIndex = - contents[position..position + 1].parse::().unwrap(); + let s: String = contents + .char_indices() + .skip(position) + .take(2) + .map(|(_u, c)| c) + .collect(); + patternIndex = s.parse::().unwrap(); + // contents[position..position + 2].parse::().unwrap(); // patternIndex = Integer.parseInt(contents.substring(position, position + 2)); position += 1; } // Also incremented below @@ -469,8 +475,8 @@ stuvwxyz{|}~\u{007F}\u{00FF}"; pub fn encode(contents: &str) -> Result, Exceptions> { let length = contents.chars().count(); - let mut memoizedCost = vec![vec![0_u32; 4]; length]; //new int[4][contents.length()]; - let mut minPath = vec![vec![Latch::NONE; 4]; length]; //new Latch[4][contents.length()]; + let mut memoizedCost = vec![vec![0_u32; length]; 4]; //new int[4][contents.length()]; + let mut minPath = vec![vec![Latch::NONE; length]; 4]; //new Latch[4][contents.length()]; encode_with_start_position(contents, Charset::NONE, 0, &mut memoizedCost, &mut minPath)?; @@ -533,9 +539,15 @@ stuvwxyz{|}~\u{007F}\u{00FF}"; i, ); } else { + let s: String = contents + .char_indices() + .skip(i) + .take(2) + .map(|(_u, c)| c) + .collect(); addPattern( &mut patterns, - (contents[i..i + 2]).parse::().unwrap(), + s.parse::().unwrap(), &mut checkSum, &mut checkWeight, i, @@ -548,20 +560,20 @@ stuvwxyz{|}~\u{007F}\u{00FF}"; } else { // charset A or B let mut patternIndex = match contents.chars().nth(i).unwrap() { - ESCAPE_FNC_1 => CODE_FNC_1, - ESCAPE_FNC_2 => CODE_FNC_2, - ESCAPE_FNC_3 => CODE_FNC_3, + ESCAPE_FNC_1 => CODE_FNC_1 as isize, + ESCAPE_FNC_2 => CODE_FNC_2 as isize, + ESCAPE_FNC_3 => CODE_FNC_3 as isize, ESCAPE_FNC_4 => { if (charset == Charset::A && latch != Latch::SHIFT) || (charset == Charset::B && latch == Latch::SHIFT) { - CODE_FNC_4_A + CODE_FNC_4_A as isize } else { - CODE_FNC_4_B + CODE_FNC_4_B as isize } } - _ => contents.chars().nth(i).unwrap() as usize - ' ' as usize, - } as isize; + _ => contents.chars().nth(i).unwrap() as isize - ' ' as isize, + }; if (charset == Charset::A && latch != Latch::SHIFT) || (charset == Charset::B && latch == Latch::SHIFT) { diff --git a/src/oned/code_128_writer_test_tase.rs b/src/oned/code_128_writer_test_tase.rs new file mode 100644 index 0000000..99a8384 --- /dev/null +++ b/src/oned/code_128_writer_test_tase.rs @@ -0,0 +1,502 @@ +/* + * Copyright 2014 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Tests {@link Code128Writer}. + */ + +const FNC1: &str = "11110101110"; +const FNC2: &str = "11110101000"; +const FNC3: &str = "10111100010"; +const FNC4A: &str = "11101011110"; +const FNC4B: &str = "10111101110"; +const START_CODE_A: &str = "11010000100"; +const START_CODE_B: &str = "11010010000"; +const START_CODE_C: &str = "11010011100"; +const SWITCH_CODE_A: &str = "11101011110"; +const SWITCH_CODE_B: &str = "10111101110"; +const QUIET_SPACE: &str = "00000"; +const STOP: &str = "1100011101011"; +const LF: &str = "10000110010"; + +use std::collections::HashMap; + +use lazy_static::lazy_static; + +use crate::{ + common::{BitArray, BitMatrix, BitMatrixTestCase}, + oned::{Code128Reader, OneDReader}, + BarcodeFormat, EncodeHintType, EncodeHintValue, EncodingHintDictionary, Exceptions, Writer, +}; + +use super::Code128Writer; +lazy_static! { + static ref writer: Code128Writer = Code128Writer::default(); +} + +#[test] +fn testEncodeWithFunc3() { + let toEncode = "\u{00f3}123"; + let expected = format!( + "{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_B, + FNC3, + // "1" "2" "3" check digit 51 + "10011100110", + "11001110010", + "11001011100", + "11101000110", + STOP, + QUIET_SPACE + ); + + let result = encode(toEncode, false, "123").expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual); + + let width = result.getWidth(); + let result = encode(toEncode, true, "123").expect("encode"); + + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testEncodeWithFunc2() { + let toEncode = "\u{00f2}123"; + let expected = format!( + "{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_B, + FNC2, + // "1" "2" "3" check digit 56 + "10011100110", + "11001110010", + "11001011100", + "11100010110", + STOP, + QUIET_SPACE + ); + + let result = encode(toEncode, false, "123").expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual); + + let width = result.getWidth(); + let result = encode(toEncode, true, "123").expect("encode"); + + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testEncodeWithFunc1() { + let toEncode = "\u{00f1}123"; + let expected = format!( + "{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_C, + FNC1, + // "12" "3" check digit 92 + "10110011100", + SWITCH_CODE_B, + "11001011100", + "10101111000", + STOP, + QUIET_SPACE + ); + + let result = encode(toEncode, false, "123").expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual); + + let width = result.getWidth(); + let result = encode(toEncode, true, "123").expect("encode"); + + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testRoundtrip() { + let toEncode = concat!("\u{00f1}", "10958", "\u{00f1}", "17160526"); + let expected = "1095817160526"; + + let encRXingResult = encode(toEncode, false, expected).expect("encode"); + + let width = encRXingResult.getWidth(); + let encRXingResult = encode(toEncode, true, expected).expect("encode"); + //Compact encoding has one latch less and encodes as STARTA,FNC1,1,CODEC,09,58,FNC1,17,16,05,26 + assert_eq!(width, encRXingResult.getWidth() + 11); +} + +#[test] +fn testLongCompact() { + //test longest possible input + let toEncode = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + encode(toEncode, true, toEncode).expect("encode"); +} + +#[test] +fn testShift() { + //compare fast to compact + let toEncode = "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"; + let result = encode(toEncode, false, toEncode).expect("encode"); + + let width = result.getWidth(); + let result = encode(toEncode, true, toEncode).expect("encode"); + + //big difference since the fast algoritm doesn't make use of SHIFT + assert_eq!(width, result.getWidth() + 253); +} + +#[test] +fn testDigitMixCompaction() { + //compare fast to compact + let toEncode = "A1A12A123A1234A12345AA1AA12AA123AA1234AA1235"; + let result = encode(toEncode, false, toEncode).expect("encode"); + + let width = result.getWidth(); + let result = encode(toEncode, true, toEncode).expect("encode"); + + //very good, no difference + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testCompaction1() { + //compare fast to compact + let toEncode = "AAAAAAAAAAA12AAAAAAAAA"; + let result = encode(toEncode, false, toEncode).expect("encode"); + + let width = result.getWidth(); + let result = encode(toEncode, true, toEncode).expect("encode"); + + //very good, no difference + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testCompaction2() { + //compare fast to compact + let toEncode = "AAAAAAAAAAA1212aaaaaaaaa"; + let result = encode(toEncode, false, toEncode).expect("encode"); + + let width = result.getWidth(); + let result = encode(toEncode, true, toEncode).expect("encode"); + + //very good, no difference + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testEncodeWithFunc4() { + let toEncode = concat!("\u{00f4}", "123"); + let expected = format!( + "{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_B, + FNC4B, + // "1" "2" "3" check digit 59 + "10011100110", + "11001110010", + "11001011100", + "11100011010", + STOP, + QUIET_SPACE + ); + + let result = encode(toEncode, false, "").expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual); + + let width = result.getWidth(); + let result = encode(toEncode, true, "").expect("encode"); + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testEncodeWithFncsAndNumberInCodesetA() { + let toEncode = concat!("\n", "\u{00f1}", "\u{00f4}", "1", "\n"); + + let expected = format!( + "{}{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_A, + LF, + FNC1, + FNC4A, + "10011100110", + LF, + "10101111000", + STOP, + QUIET_SPACE + ); + + let result = encode(toEncode, false, "").expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + + assert_eq!(expected, actual); + + let width = result.getWidth(); + let result = encode(toEncode, true, "").expect("encode"); + assert_eq!(width, result.getWidth()); +} + +#[test] +fn testEncodeSwitchBetweenCodesetsAAndB() { + // start with A switch to B and back to A + testEncode( + "\0ABab\u{0010}", + &format!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_A, + // "\0" "A" "B" Switch to B "a" "b" + "10100001100", + "10100011000", + "10001011000", + SWITCH_CODE_B, + "10010110000", + "10010000110", + // Switch to A "\u0010" check digit + SWITCH_CODE_A, + "10100111100", + "11001110100", + STOP, + QUIET_SPACE + ), + ); + + // start with B switch to A and back to B + // the compact encoder encodes this shorter as STARTB,a,b,SHIFT,NUL,a,b + testEncode( + "ab\0ab", + &format!( + "{}{}{}{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_B, + // "a" "b" Switch to A "\0" Switch to B + "10010110000", + "10010000110", + SWITCH_CODE_A, + "10100001100", + SWITCH_CODE_B, + // "a" "b" check digit + "10010110000", + "10010000110", + "11010001110", + STOP, + QUIET_SPACE + ), + ); +} + +fn testEncode(toEncode: &str, expected: &str) { + let result = encode(toEncode, false, toEncode).expect("encode"); + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual, "{}", toEncode); + + let width = result.getWidth(); + let result = encode(toEncode, true, toEncode).expect("encode"); + assert!(result.getWidth() <= width); +} + +#[test] +#[should_panic] +fn testEncodeWithForcedCodeSetFailureCodeSetABadCharacter() { + // Lower case characters should not be accepted when the code set is forced to A. + let toEncode = "ASDFx0123"; + + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("A".to_string()), + ); + writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); +} + +#[test] +#[should_panic] +fn testEncodeWithForcedCodeSetFailureCodeSetBBadCharacter() { + let toEncode = "ASdf\00123"; // \0 (ascii value 0) + // Characters with ASCII value below 32 should not be accepted when the code set is forced to B. + + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("B".to_string()), + ); + // let hints = new EnumMap<>(EncodeHintType.class); + // hints.put(EncodeHintType.FORCE_CODE_SET, "B"); + writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); +} + +#[test] +#[should_panic] +fn testEncodeWithForcedCodeSetFailureCodeSetCBadCharactersNonNum() { + let toEncode = "123a5678"; + // Non-digit characters should not be accepted when the code set is forced to C. + + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("C".to_string()), + ); + // let hints = new EnumMap<>(EncodeHintType.class); + // hints.put(EncodeHintType.FORCE_CODE_SET, "C"); + writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); +} + +#[test] +#[should_panic] +fn testEncodeWithForcedCodeSetFailureCodeSetCBadCharactersFncCode() { + let toEncode = "123\u{00f2}a678"; + // Function codes other than 1 should not be accepted when the code set is forced to C. + + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("C".to_string()), + ); + writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); +} + +#[test] +#[should_panic] +fn testEncodeWithForcedCodeSetFailureCodeSetCWrongAmountOfDigits() { + let toEncode = "123456789"; + // An uneven amount of digits should not be accepted when the code set is forced to C. + + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("C".to_string()), + ); + writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); +} + +#[test] +fn testEncodeWithForcedCodeSetFailureCodeSetA() { + let toEncode = "AB123"; + // would default to B "A" "B" "1" + let expected = format!( + "{}{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_A, + "10100011000", + "10001011000", + "10011100110", + // "2" "3" check digit 10 + "11001110010", + "11001011100", + "11001000100", + STOP, + QUIET_SPACE + ); + + // let hints = new EnumMap<>(EncodeHintType.class); + // hints.put(EncodeHintType.FORCE_CODE_SET, "A"); + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("A".to_string()), + ); + let result = writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual); +} + +#[test] +fn testEncodeWithForcedCodeSetFailureCodeSetB() { + let toEncode = "1234"; + // would default to C "1" "2" "3" + let expected = format!( + "{}{}{}{}{}{}{}{}{}", + QUIET_SPACE, + START_CODE_B, + "10011100110", + "11001110010", + "11001011100", + // "4" check digit 88 + "11001001110", + "11110010010", + STOP, + QUIET_SPACE + ); + + // let hints = new EnumMap<>(EncodeHintType.class); + // hints.put(EncodeHintType.FORCE_CODE_SET, "B"); + let mut hints = HashMap::new(); //new EnumMap<>(EncodeHintType.class); + hints.insert( + EncodeHintType::FORCE_CODE_SET, + EncodeHintValue::ForceCodeSet("B".to_string()), + ); + let result = writer + .encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints) + .expect("encode"); + + let actual = BitMatrixTestCase::matrix_to_string(&result); + assert_eq!(expected, actual); +} + +fn encode(toEncode: &str, compact: bool, expectedLoopback: &str) -> Result { + let mut reader = Code128Reader::default(); + + let mut hints: EncodingHintDictionary = HashMap::new(); + if compact { + hints.insert( + EncodeHintType::CODE128_COMPACT, + EncodeHintValue::Code128Compact(true), + ); + } + let encRXingResult = + writer.encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints)?; + if !expectedLoopback.is_empty() { + let row = encRXingResult.getRow(0, BitArray::new()); + let rtRXingResult = reader.decodeRow(0, &row, &HashMap::new())?; + let actual = rtRXingResult.getText(); + assert_eq!(expectedLoopback, actual); + } + if compact { + //check that what is encoded compactly yields the same on loopback as what was encoded fast. + let row = encRXingResult.getRow(0, BitArray::new()); + let rtRXingResult = reader.decodeRow(0, &row, &HashMap::new())?; + let actual = rtRXingResult.getText(); + let encRXingResultFast = writer.encode(toEncode, &BarcodeFormat::CODE_128, 0, 0)?; + let row = encRXingResultFast.getRow(0, BitArray::new()); + let rtRXingResult = reader.decodeRow(0, &row, &HashMap::new())?; + assert_eq!(rtRXingResult.getText(), actual); + } + Ok(encRXingResult) +} diff --git a/src/oned/mod.rs b/src/oned/mod.rs index 1136963..24cd73d 100644 --- a/src/oned/mod.rs +++ b/src/oned/mod.rs @@ -67,3 +67,6 @@ pub use itf_writer::*; mod code_128_writer; pub use code_128_writer::*; + +#[cfg(test)] +mod code_128_writer_test_tase;