Viewing is open to everyone. Downloading and starring need a GitHub sign-in.
Sign in with GitHub
DecoderTests.cs
v0.1.0-build.85
Latest
Commit ede38f5
Sign in with GitHub to download. Each download is recorded with your GitHub username.
| 1 | using System; |
| 2 | using System.Text; |
| 3 | using Xunit; |
| 4 | |
| 5 | namespace OpenCKey.Tests |
| 6 | { |
| 7 | public class DecoderTests |
| 8 | { |
| 9 | [Fact] |
| 10 | public void RoundTripsTextThroughTheFullFramePipeline() |
| 11 | { |
| 12 | var symbol = CKeySymbol.Encode("https://openckey.org/hello"); |
| 13 | byte[] frame = Frames.Frame(symbol, out int w, out int h, out int stride); |
| 14 | CKeyResult? result = CKeyDecoder.Decode(frame, w, h, stride); |
| 15 | Assert.NotNull(result); |
| 16 | Assert.Equal(CKeyProfile.Scalable, result!.Profile); |
| 17 | Assert.Equal(symbol.Version, result.Version); |
| 18 | Assert.Equal(Layout.Standard, result.Layout); |
| 19 | Assert.Equal("https://openckey.org/hello", result.Text); |
| 20 | Assert.Equal(8, result.Quad.Length); |
| 21 | Assert.Equal(CKeyActionKind.Web, result.Action!.Kind); |
| 22 | Assert.Equal("Open openckey.org", result.Action.Label); |
| 23 | Assert.StartsWith("Profile 0 · v", result.ProfileName); |
| 24 | } |
| 25 | |
| 26 | [Fact] |
| 27 | public void RoundTripsPrintLayoutAndBinaryPayloads() |
| 28 | { |
| 29 | var payload = new byte[] { 0, 1, 2, 0xff, 0xfe, 7, 0x80 }; |
| 30 | var symbol = CKeySymbol.Encode(payload, layout: Layout.Print); |
| 31 | byte[] frame = Frames.Frame(symbol, out int w, out int h, out int stride); |
| 32 | CKeyResult? result = CKeyDecoder.Decode(frame, w, h, stride); |
| 33 | Assert.NotNull(result); |
| 34 | Assert.Equal(Layout.Print, result!.Layout); |
| 35 | Assert.Equal(payload, result.Payload); |
| 36 | Assert.Null(result.Text); |
| 37 | Assert.Null(result.Action); |
| 38 | Assert.Equal("000102fffe0780", result.PayloadHex); |
| 39 | } |
| 40 | |
| 41 | [Fact] |
| 42 | public void RoundTripsALargerVersion() |
| 43 | { |
| 44 | string text = new string('x', 600); |
| 45 | var symbol = CKeySymbol.Encode(text); |
| 46 | Assert.True(symbol.Version > 5); |
| 47 | // About 4 pixels per module. |
| 48 | int size = (int)Math.Ceiling(31.0 * 4 * symbol.ModulesAcross / 29.0); |
| 49 | var gray = symbol.RenderGray(size, RasterPolicy.Binary); |
| 50 | int w = size + 200, h = size + 160, stride = w; |
| 51 | byte[] frame = Frames.Embed(gray, w, h, stride, 100, 80); |
| 52 | Assert.Equal(text, CKeyDecoder.Decode(frame, w, h, stride)?.Text); |
| 53 | } |
| 54 | |
| 55 | [Fact] |
| 56 | public void FindBordersThenDecodeCandidate() |
| 57 | { |
| 58 | var symbol = CKeySymbol.Encode("split detection"); |
| 59 | byte[] frame = Frames.Frame(symbol, out int w, out int h, out int stride); |
| 60 | double[][] borders = CKeyDecoder.FindBorders(frame, w, h, stride); |
| 61 | Assert.NotEmpty(borders); |
| 62 | Assert.Equal("split detection", CKeyDecoder.DecodeCandidate(frame, w, h, stride, borders[0])?.Text); |
| 63 | } |
| 64 | |
| 65 | [Fact] |
| 66 | public void BlankFrameDecodesNothing() |
| 67 | { |
| 68 | var frame = new byte[320 * 240]; |
| 69 | Array.Fill(frame, (byte)200); |
| 70 | Assert.Null(CKeyDecoder.Decode(frame, 320, 240, 320)); |
| 71 | } |
| 72 | |
| 73 | [Fact] |
| 74 | public void ValidatesFrameArguments() |
| 75 | { |
| 76 | var frame = new byte[100]; |
| 77 | Assert.Throws<ArgumentOutOfRangeException>(() => CKeyDecoder.Decode(frame, 0, 10, 10)); |
| 78 | Assert.Throws<ArgumentOutOfRangeException>(() => CKeyDecoder.Decode(frame, 10, 10, 9)); |
| 79 | Assert.Throws<ArgumentException>(() => CKeyDecoder.Decode(frame, 10, 11, 10)); |
| 80 | Assert.Throws<ArgumentException>(() => CKeyDecoder.DecodeCandidate(frame, 10, 10, 10, new double[7])); |
| 81 | } |
| 82 | |
| 83 | [Fact] |
| 84 | public void DecodeIsThreadSafe() |
| 85 | { |
| 86 | var symbol = CKeySymbol.Encode("parallel"); |
| 87 | byte[] frame = Frames.Frame(symbol, out int w, out int h, out int stride); |
| 88 | var texts = new string?[8]; |
| 89 | System.Threading.Tasks.Parallel.For(0, texts.Length, i => texts[i] = CKeyDecoder.Decode(frame, w, h, stride)?.Text); |
| 90 | Assert.All(texts, t => Assert.Equal("parallel", t)); |
| 91 | } |
| 92 | |
| 93 | [Fact] |
| 94 | public void UnicodeText() |
| 95 | { |
| 96 | const string text = "Grüße · 東京 · ✓"; |
| 97 | var symbol = CKeySymbol.Encode(text); |
| 98 | Assert.Equal(Encoding.UTF8.GetByteCount(text), symbol.PayloadLength); |
| 99 | byte[] frame = Frames.Frame(symbol, out int w, out int h, out int stride); |
| 100 | Assert.Equal(text, CKeyDecoder.Decode(frame, w, h, stride)?.Text); |
| 101 | } |
| 102 | } |
| 103 | } |