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
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 | |
| 5 | import android.graphics.Bitmap; |
| 6 | import java.nio.charset.StandardCharsets; |
| 7 | import java.util.Arrays; |
| 8 | |
| 9 | import org.openckey.ckey.CKey; |
| 10 | import org.openckey.ckey.CKeyDecoder; |
| 11 | import org.openckey.ckey.CKeyException; |
| 12 | import org.openckey.ckey.CKeyPayload; |
| 13 | import org.openckey.ckey.CKeyPayloadAction; |
| 14 | import org.openckey.ckey.CKeyResult; |
| 15 | import org.openckey.ckey.CKeyScanner; |
| 16 | import org.openckey.ckey.CKeyStyle; |
| 17 | import org.openckey.ckey.CKeySymbol; |
| 18 | import org.openckey.ckey.CKeyTelemetryCounters; |
| 19 | import org.openckey.ckey.EccLevel; |
| 20 | import org.openckey.ckey.Layout; |
| 21 | import org.openckey.ckey.RasterPolicy; |
| 22 | import org.openckey.ckey.StylePolicy; |
| 23 | |
| 24 | public 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 | } |