aboutsummaryrefslogtreecommitdiff
path: root/test/boltex/pack_stream_test.exs
blob: 86476efd165ea4b0cd175383018bc274d89a27dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
defmodule Boltex.PackStreamTest do
  use ExUnit.Case

  alias Boltex.{Utils, PackStream}

  # A lot of the examples have been taken from
  # https://github.com/neo4j/neo4j-python-driver/blob/1.1/neo4j/v1/packstream.py
  # """

  doctest Boltex.PackStream

  test "encodes null" do
    assert PackStream.encode(nil) == <<0xC0>>
  end

  test "encodes boolean" do
    assert PackStream.encode(true)   ==  <<0xC3>>
    assert PackStream.encode(false)  ==  <<0xC2>>
  end

  test "encodes atom" do
    assert PackStream.encode(:hello) ==  <<0x85, 0x68, 0x65, 0x6C, 0x6C, 0x6F>>
  end

  test "encodes integer" do
    assert PackStream.encode(0)   == << 0x00 >>
    assert PackStream.encode(42)  == << 0x2A >>
    assert PackStream.encode(-42) == << 0xC8, 0xD6 >>
    assert PackStream.encode(420) == << 0xC9, 0x01, 0xA4 >>
  end

  test "encodes string" do
    assert PackStream.encode("")      == << 0x80 >>
    assert PackStream.encode("Short") == <<0x85, 0x53, 0x68, 0x6F, 0x72, 0x74>>

    long_8 = "This is a räther löng string" # 30 bytes due to umlauts
    assert <<0xD0, 0x1E, _ :: binary-size(30)>> = PackStream.encode(long_8)

    long_16 =
      """
      For encoded string containing fewer than 16 bytes, including empty strings,
      the marker byte should contain the high-order nibble `1000` followed by a
      low-order nibble containing the size. The encoded data then immediately
      follows the marker.

      For encoded string containing 16 bytes or more, the marker 0xD0, 0xD1 or
      0xD2 should be used, depending on scale. This marker is followed by the
      size and the UTF-8 encoded data.
      """
    assert <<0xD1, 0x01, 0xA5, _ :: binary-size(421)>> = PackStream.encode(long_16)
  end

  test "encodes list" do
    assert PackStream.encode([]) == <<0x90>>
  end

  test "encodes map" do
    assert PackStream.encode(%{}) == <<0xA0>>
  end

  test "decodes null" do
    assert PackStream.decode(<<0xC0>>) == [nil]
  end

  test "decodes boolean" do
    assert PackStream.decode(<<0xC3>>) == [true]
    assert PackStream.decode(<<0xC2>>) == [false]
  end

  test "decodes floats" do
    positive = ~w(C1 3F F1 99 99 99 99 99 9A) |> Utils.hex_decode
    negative = ~w(C1 BF F1 99 99 99 99 99 9A) |> Utils.hex_decode

    assert PackStream.decode(positive) == [1.1]
    assert PackStream.decode(negative) == [-1.1]
  end

  test "decodes integers" do
    assert PackStream.decode(<<0x2A>>)                            == [42]
    assert PackStream.decode(<<0xC8, 0x2A>>)                      == [42]
    assert PackStream.decode(<<0xC9, 0, 0x2A>>)                   == [42]
    assert PackStream.decode(<<0xCA, 0, 0, 0, 0x2A>>)             == [42]
    assert PackStream.decode(<<0xCB, 0, 0, 0, 0, 0, 0, 0, 0x2A>>) == [42]
  end

  test "decodes strings" do
    longstr =
      ~w(D0 1A 61 62  63 64 65 66  67 68 69 6A  6B 6C 6D 6E 6F 70 71 72  73 74 75 76  77 78 79 7A)
      |> Utils.hex_decode

    specialcharstr =
      ~w(D0 18 45 6E  20 C3 A5 20  66 6C C3 B6  74 20 C3 B6 76 65 72 20  C3 A4 6E 67  65 6E)
      |> Utils.hex_decode


    assert PackStream.decode(<<0x80>>)       == [""]
    assert PackStream.decode(<<0x81, 0x61>>) == ["a"]
    assert PackStream.decode(longstr)        == ["abcdefghijklmnopqrstuvwxyz"]
    assert PackStream.decode(specialcharstr) == ["En å flöt över ängen"]
  end

  test "decodes lists" do
    longlist =
      ~w(D4 14 01 02 03 04 05 06  07 08 09 00)
      |> Utils.hex_decode

    assert PackStream.decode(<<0x90>>)                   == [[]]
    assert PackStream.decode(<<0x93, 0x01, 0x02, 0x03>>) == [[1, 2, 3]]
    assert PackStream.decode(longlist)                   == [[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]]
    assert PackStream.decode(<<0xD7, 0x01, 0x02, 0xDF>>) == [[1, 2]]
  end

  test "decodes maps" do
    assert PackStream.decode(<<0xA0>>) == [%{}]
    assert PackStream.decode(<<0xA1, 0x81, 0x61, 0x01>>) == [%{"a" => 1}]
    assert PackStream.decode(<<0xAB, 0x81, 0x61, 0x01, 0xDF>>) == [%{"a" => 1}]
  end

end