aboutsummaryrefslogtreecommitdiff
path: root/test/codes
diff options
context:
space:
mode:
Diffstat (limited to 'test/codes')
-rw-r--r--test/codes/CodeCacheTest.mc10
-rw-r--r--test/codes/DataMatrixTest.mc110
-rw-r--r--test/codes/Pdf417Test.mc70
3 files changed, 187 insertions, 3 deletions
diff --git a/test/codes/CodeCacheTest.mc b/test/codes/CodeCacheTest.mc
index e09d902..812acc9 100644
--- a/test/codes/CodeCacheTest.mc
+++ b/test/codes/CodeCacheTest.mc
@@ -39,7 +39,7 @@ function codeCacheOfLockedEntriesNeedsTheSession(logger as Test.Logger) as Boole
e.type = Codes.QR;
e.locked = true;
var id = vault.add(e);
- vault.saveCodeCache(id, [3, 1, 4, 0xE0]b);
+ vault.saveCodeCache(id, [3, 1, 4, 1, 0xE0]b);
vault.lock();
var code = 0;
try {
@@ -49,6 +49,10 @@ function codeCacheOfLockedEntriesNeedsTheSession(logger as Test.Logger) as Boole
}
StorageFixtures.unlock(vault, StorageFixtures.PIN);
var back = vault.loadCodeCache(id);
- return code == VaultError.LOCKED && back != null && Bytes.equal(back, [3, 1, 4, 0xE0]b)
- && Codes.Matrix.fromBytes([3, 1, 4, 0xE0]b) != null && Codes.Matrix.fromBytes([3, 1, 4]b) == null;
+ var pdf = new Codes.Matrix(3, 2, 2, [1, 0, 1, 0, 1, 1]b);
+ pdf.rowHeight = 3;
+ var round = Codes.Matrix.fromBytes(pdf.toBytes());
+ return code == VaultError.LOCKED && back != null && Bytes.equal(back, [3, 1, 4, 1, 0xE0]b)
+ && Codes.Matrix.fromBytes([3, 1, 4, 1, 0xE0]b) != null && Codes.Matrix.fromBytes([3, 1, 4]b) == null
+ && round != null && round.rowHeight == 3 && Bytes.equal(round.modules, [1, 0, 1, 0, 1, 1]b);
}
diff --git a/test/codes/DataMatrixTest.mc b/test/codes/DataMatrixTest.mc
new file mode 100644
index 0000000..ff3cbbe
--- /dev/null
+++ b/test/codes/DataMatrixTest.mc
@@ -0,0 +1,110 @@
+// Author: cirakg & claude ai
+// Summary: Tests for the Data Matrix encoder: ppf.datamatrix references (ASCII), Base256 and upper-shift decoding dumps, limits.
+
+import Toybox.Lang;
+import Toybox.Test;
+
+(:test)
+module MatrixFixtures {
+
+ function packedHex(m as Codes.Matrix) as String {
+ var bits = m.modules;
+ var out = new [(bits.size() + 7) / 8]b;
+ for (var i = 0; i < bits.size(); i++) {
+ if (bits[i] == 1) {
+ out[i / 8] = out[i / 8] | (0x80 >> (i % 8));
+ }
+ }
+ return Bytes.toHex(out);
+ }
+
+ // A line tools/check_codes.py decodes with zxing-cpp.
+ function dump(logger as Test.Logger, symbology as Number, text as String, m as Codes.Matrix) as Void {
+ logger.debug("MATRIXDUMP " + symbology + " " + m.width + " " + m.height + " " + m.rowHeight + " " + m.quiet + " "
+ + Bytes.toHex(Bytes.fromUtf8(text)) + " " + packedHex(m));
+ }
+}
+
+// README 12.4 check 1: identical to ppf.datamatrix in ASCII mode, from
+// 10 x 10 to 144 x 144 (multi-region and multi-block sizes).
+(:test)
+function dataMatrixMatchesReference(logger as Test.Logger) as Boolean {
+ var rows = CodeVectors.DATAMATRIX;
+ for (var i = 0; i < rows.size(); i++) {
+ var row = rows[i] as Array;
+ var payload = row[0] as String;
+ var result = DataMatrix.encode(payload);
+ if (result instanceof Codes.CodeError) {
+ logger.error("row " + i + ": " + result.message);
+ return false;
+ }
+ var expectedSize = row[1] as Number;
+ var expected = row[2] as String;
+ var got = MatrixFixtures.packedHex(result);
+ if (result.width != expectedSize || !got.equals(expected)) {
+ logger.error("row " + i + " '" + Text.clip(payload, 20) + "': size " + result.width + ", reference " + expectedSize);
+ return false;
+ }
+ }
+ logger.debug("CODES datamatrix reference rows=" + rows.size());
+ return true;
+}
+
+// README 12.4 check 2: Base256 (UTF-8), Upper Shift and plain payloads,
+// decoded by tools/check_codes.py.
+(:test)
+function dataMatrixDumpForDecoding(logger as Test.Logger) as Boolean {
+ var payloads = ["Zürich", "Ünïcödé 😀 fake card 0042", "é", "1234567890", "Member: fake-0042, valid 2027-12-31",
+ "ÄÖÜäöüß" + "ÄÖÜäöüß" + "ÄÖÜäöüß", "abc"];
+ var long = "";
+ for (var i = 0; i < 30; i++) {
+ long += "é0123456789";
+ }
+ payloads.add(long);
+ var xs = "";
+ for (var i = 0; i < 50; i++) {
+ xs += "xxxxxxxxxx";
+ }
+ payloads.add(xs); // 88 x 88: 4 x 4 regions, 4 interleaved blocks
+ var digits = "";
+ for (var i = 0; i < 110; i++) {
+ digits += "0123456789";
+ }
+ payloads.add(digits); // 88 x 88 in digit pairs, comparable with zint
+ for (var i = 0; i < payloads.size(); i++) {
+ var text = payloads[i] as String;
+ var result = DataMatrix.encode(text);
+ if (result instanceof Codes.CodeError) {
+ logger.error("'" + text + "': " + result.message);
+ return false;
+ }
+ MatrixFixtures.dump(logger, Codes.DATAMATRIX, text, result);
+ }
+ return true;
+}
+
+(:test)
+function dataMatrixLimits(logger as Test.Logger) as Boolean {
+ var big = "";
+ for (var i = 0; i < 160; i++) {
+ big += "abcdefghij";
+ }
+ // (Separate checks: one long && chain of instanceof tests made the
+ // compiler run out of memory.)
+ if (!(DataMatrix.encode(big) instanceof Codes.CodeError)) {
+ logger.error("too long text was accepted");
+ return false;
+ }
+ if (!(DataMatrix.encode("") instanceof Codes.CodeError)) {
+ logger.error("empty text was accepted");
+ return false;
+ }
+ // Base256 is chosen when cheaper than Upper Shift for every byte.
+ var b256 = DataMatrix.codewords(Bytes.fromUtf8("ÄÖÜ"));
+ if (b256[0] != DataMatrix.BASE256_LATCH) {
+ logger.error("Base256 not chosen");
+ return false;
+ }
+ var ascii = DataMatrix.codewords(Bytes.fromUtf8("A1234"));
+ return ascii.size() == 3 && ascii[0] == 66 && ascii[1] == 142;
+}
diff --git a/test/codes/Pdf417Test.mc b/test/codes/Pdf417Test.mc
new file mode 100644
index 0000000..8939e03
--- /dev/null
+++ b/test/codes/Pdf417Test.mc
@@ -0,0 +1,70 @@
+// Author: cirakg & claude ai
+// Summary: Tests for the PDF417 encoder: pdf417gen reference rows, decoding dumps of screen-fitted symbols, limits.
+
+import Toybox.Lang;
+import Toybox.Test;
+
+// README 12.4 check 1: the same rows as pdf417gen for fixed columns and
+// levels (compaction, padding, EC, row indicators and patterns).
+(:test)
+function pdf417MatchesReference(logger as Test.Logger) as Boolean {
+ var rows = CodeVectors.PDF417;
+ for (var i = 0; i < rows.size(); i++) {
+ var row = rows[i] as Array;
+ var payload = row[0] as String;
+ var result = Pdf417.encode(payload, row[1] as Number, row[2] as Number);
+ if (result instanceof Codes.CodeError) {
+ logger.error("row " + i + ": " + result.message);
+ return false;
+ }
+ var expectedRows = row[3] as Number;
+ var expectedWidth = row[4] as Number;
+ if (result.height != expectedRows || result.rowHeight != Pdf417.ROW_HEIGHT || result.width != expectedWidth) {
+ logger.error("row " + i + " '" + Text.clip(payload, 20) + "': " + result.width + " x " + result.height
+ + ", reference " + expectedWidth + " x " + expectedRows);
+ return false;
+ }
+ var got = MatrixFixtures.packedHex(result);
+ if (!got.equals(row[5] as String)) {
+ logger.error("row " + i + " '" + Text.clip(payload, 20) + "' differs");
+ return false;
+ }
+ }
+ logger.debug("CODES pdf417 reference rows=" + rows.size());
+ return true;
+}
+
+// README 12.4 check 2: symbols laid out for real screens (columns chosen to
+// fit), decoded by tools/check_codes.py.
+(:test)
+function pdf417DumpForDecoding(logger as Test.Logger) as Boolean {
+ var payloads = ["Boarding pass FAKE 0042 seat 12A", "Zürich ✓ Ünïcödé fake", "12345678901234567890123456789",
+ "https://example.com/member/fake?id=0042&level=gold", "a"];
+ var screens = [[218, 218, true], [390, 390, true], [320, 360, false]];
+ for (var i = 0; i < payloads.size(); i++) {
+ var s = screens[i % screens.size()] as Array;
+ var job = new Pdf417.Pdf417Job(payloads[i] as String, 1, s[0] as Number, s[1] as Number, s[2] as Boolean);
+ Jobs.runToCompletion(job, 1);
+ var m = job.matrix();
+ if (job.error != null || m == null) {
+ logger.error("'" + payloads[i] + "': " + job.error);
+ return false;
+ }
+ MatrixFixtures.dump(logger, Codes.PDF417, payloads[i] as String, m);
+ }
+ return true;
+}
+
+(:test)
+function pdf417Limits(logger as Test.Logger) as Boolean {
+ if (!(Pdf417.encode("", 3, 2) instanceof Codes.CodeError)) {
+ logger.error("empty text accepted");
+ return false;
+ }
+ // Two codewords in 30 columns is a single row: PDF417 needs 3.
+ if (!(Pdf417.encode("ab", 30, 0) instanceof Codes.CodeError)) {
+ logger.error("a one-row symbol was accepted");
+ return false;
+ }
+ return Pdf417.autoLevel(40) == 2 && Pdf417.autoLevel(41) == 3 && Pdf417.autoLevel(320) == 4 && Pdf417.autoLevel(321) == 5;
+}