Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

KotlinApiCheck.java

v0.1.0-build.85 Latest Commit ede38f5

Size
5.5 KB
Lines
96
Language
plaintext
SHA-256
d296b0389f86…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1// Exercises the Kotlin public API (compiled from ckey/src/main/kotlin) from
2// plain Java on a desktop JVM, with android.* replaced by tiny stubs. Run by
3// run.sh when a Kotlin compiler is available.
4
5import android.graphics.Bitmap;
6import java.nio.charset.StandardCharsets;
7import java.util.Arrays;
8
9import org.openckey.ckey.CKey;
10import org.openckey.ckey.CKeyDecoder;
11import org.openckey.ckey.CKeyException;
12import org.openckey.ckey.CKeyPayload;
13import org.openckey.ckey.CKeyPayloadAction;
14import org.openckey.ckey.CKeyResult;
15import org.openckey.ckey.CKeyScanner;
16import org.openckey.ckey.CKeyStyle;
17import org.openckey.ckey.CKeySymbol;
18import org.openckey.ckey.CKeyTelemetryCounters;
19import org.openckey.ckey.EccLevel;
20import org.openckey.ckey.Layout;
21import org.openckey.ckey.RasterPolicy;
22import org.openckey.ckey.StylePolicy;
23
24public final class KotlinApiCheck {
25 static int checks = 0;
26
27 static void check(boolean ok, String what) {
28 checks++;
29 if (!ok) throw new AssertionError("FAILED: " + what);
30 System.out.println("ok " + what);
31 }
32
33 public static void main(String[] args) {
34 String url = "https://openckey.org/kotlin";
35 CKeySymbol symbol = CKeySymbol.encode(url);
36 check(symbol.getLevel() == EccLevel.M && symbol.getLayout() == Layout.STANDARD && symbol.getPayloadLength() == url.length(), "encode(text) defaults: " + symbol);
37 CKeySymbol print = CKeySymbol.encode(url.getBytes(StandardCharsets.UTF_8), 0, EccLevel.Q, Layout.PRINT);
38 check(print.getLayout() == Layout.PRINT && print.getLevel() == EccLevel.Q, "encode(bytes, 0, Q, PRINT)");
39 check(CKeySymbol.capacity(31) > 4000, "capacity(31) = " + CKeySymbol.capacity(31));
40
41 // toBitmap: premultiplied bytes handed to copyPixelsFromBuffer.
42 Bitmap opaque = symbol.toBitmap(300);
43 check(opaque.getWidth() == 300 && !opaque.hasAlpha(), "toBitmap(300) opaque");
44 Bitmap clear = symbol.toBitmap(300, RasterPolicy.COVERAGE, true, null);
45 boolean premultiplied = true;
46 for (int p = 0; p < clear.memory.length; p += 4)
47 for (int c = 0; c < 3; c++) if ((clear.memory[p + c] & 0xff) > (clear.memory[p + 3] & 0xff)) premultiplied = false;
48 check(clear.hasAlpha() && premultiplied, "toBitmap(transparent) is premultiplied");
49
50 // Round trip through the public decoder (Bitmap helper composites over white).
51 CKeyResult result = org.openckey.ckey.CKeyBitmaps.decode(CKeyDecoder.INSTANCE, clear);
52 check(result != null && url.equals(result.getText()), "Bitmap -> CKeyDecoder.decode: " + result);
53 check(result.getAction() instanceof CKeyPayloadAction.Web && ((CKeyPayloadAction.Web) result.getAction()).getHost().equals("openckey.org"), "result action Web(openckey.org)");
54
55 byte[] gray = symbol.toGray(256);
56 CKeyResult direct = CKeyDecoder.decode(gray, 256, 256);
57 check(direct != null && Arrays.equals(direct.getBytes(), url.getBytes(StandardCharsets.UTF_8)), "toGray -> decode(gray, w, h)");
58
59 check(symbol.toPng(128).length > 0 && symbol.toSvg().contains("<svg") && symbol.toPdf().length > 0, "toPng / toSvg / toPdf");
60
61 CKeyStyle concept = CKeyStyle.getCONCEPT();
62 check(concept.getAccents().size() == 2 && concept.getPolicy() == StylePolicy.STRICT, "CKeyStyle.CONCEPT from the core");
63 check(CKeyStyle.getDEFAULT().getInk() == 0 && CKeyStyle.getDEFAULT().getBackground() == 0xFFFFFF, "CKeyStyle.DEFAULT black on white");
64 check(CKeyStyle.getDEFAULT().equals(new CKeyStyle()), "Kotlin defaults equal ckey_style_default");
65 try {
66 CKeyStyle bad = new CKeyStyle(0xFFFFFF, 0xFFFFFF, 0xF4F4F4, 0xF4F4F4, java.util.Collections.emptyList(), 0,
67 org.openckey.ckey.ModuleShape.ROUNDED, org.openckey.ckey.RingStyle.JOINED, org.openckey.ckey.RayCap.ROUND,
68 0, 0, 0, null, null, 0, false, StylePolicy.STRICT);
69 symbol.toBitmap(128, RasterPolicy.COVERAGE, false, bad);
70 check(false, "low-contrast style should be refused");
71 } catch (CKeyException e) {
72 check(e.getStatus() == CKeyException.INVALID_ARGUMENT, "strict style refused: " + e.getMessage());
73 }
74
75 // Telemetry property.
76 check(CKey.getTelemetry() == 1, "CKey.telemetry defaults to 1");
77 try { CKey.setTelemetry(3); check(false, "3 accepted"); } catch (IllegalArgumentException e) { check(true, "CKey.telemetry = 3 -> IllegalArgumentException"); }
78 check(CKey.getTelemetry() == 1, "mode unchanged after the invalid value");
79
80 CKeyScanner scanner = new CKeyScanner();
81 scanner.start();
82 byte[] blank = new byte[64 * 64];
83 check(scanner.process(blank, 64, 64, 64, 0) == null, "scanner: blank frame");
84 check(scanner.process(gray, 256, 256, 256, 0) != null, "scanner: decode");
85 check(scanner.process(gray, 256, 256, 256, 0) == null, "scanner: frames ignored after a decode");
86 scanner.stop();
87 CKeyTelemetryCounters counters = CKey.telemetryCounters();
88 check(counters != null && counters.getSessionsSucceeded() >= 1 && counters.getFrames() >= 2 && counters.getDecoded().get(0) >= 1, "telemetry counters " + counters);
89 CKey.setTelemetry(0);
90 check(CKey.getTelemetry() == 0 && CKey.telemetryCounters().getFrames() == 0, "CKey.telemetry = 0 purges");
91 CKey.setTelemetry(1);
92
93 check(CKeyPayload.classify("javascript:alert(1)") == null, "javascript: is plain text");
94 System.out.println("KotlinApiCheck: " + checks + " checks passed");
95 }
96}