diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore index 12179ea..f1892af 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ # The directory Mix downloads your dependencies sources to. /deps/ -# Where 3rd-party dependencies like ExDoc output generated docs. +# Where third-party dependencies like ExDoc output generated docs. /doc/ # Ignore .fetch files in case you like to edit your project deps locally. @@ -18,3 +18,6 @@ erl_crash.dump # Also ignore archive artifacts (built via "mix archive.build"). *.ez + +# Ignore package tarball (built via "mix hex.build"). +velocy-*.tar diff --git a/LICENSE b/LICENSE index 261eeb9..34d7c20 100644 --- a/LICENSE +++ b/LICENSE @@ -1,192 +1,4 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] +Copyright 2017 Manuel Pöter Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 513db69..c65c99b 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,32 @@ # VelocyPack -Parser and Generator for [VelocyPack](https://github.com/arangodb/velocypack) +An Elixir parser and generator for [VelocyPack](https://github.com/arangodb/velocypack/blob/master/VelocyPack.md) v1. The implementation is heavily inspired by [Jason](https://github.com/michalmuskala/jason) and borrows some code (specifically the Codegen module). -## Installation - -If [available in Hex](https://hex.pm/docs/publish), the package can be installed -by adding `velocy_pack` to your list of dependencies in `mix.exs`: +## Examples ```elixir -def deps do - [ - {:velocy_pack, "~> 0.1.0"} - ] -end -``` +iex> {:ok, vpack} = VelocyPack.encode(10.2312514) +{:ok, <<27, 245, 78, 96, 149, 102, 118, 36, 64>>} +iex> VelocyPack.decode(vpack) +{:ok, 10.2312514} + +iex> vpack = VelocyPack.encode!(%{a: "a", b: %{bool: true, float: 10.2312514}}) +<<11, 37, 2, 65, 97, 65, 97, 65, 98, 11, 26, 2, 68, 98, 111, 111, 108, 26, 69, 102, 108, 111, 97, 116, 27, 245, 78, 96, 149, 102, 118, 36, 64, 3, 9, 3, 7>> +iex> VelocyPack.decode!(vpack) +%{"a" => "a", "b" => %{"bool" => true, "float" => 10.2312514}} + +iex> VelocyPack.decode(<<11>>) +{:error, %VelocyPack.Error{message: "unexpected sequence", dump: nil}} + +iex> VelocyPack.decode!(<<11>>) +** (VelocyPack.Error) unexpected sequence -Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) -and published on [HexDocs](https://hexdocs.pm). Once published, the docs can -be found at [https://hexdocs.pm/velocy_pack](https://hexdocs.pm/velocy_pack). +iex> VelocyPack.decode(<<11, 823891328731>>) +{:error, %VelocyPack.Error{message: "unexpected byte", dump: "<<0xDB>>"}} +iex> VelocyPack.decode!(<<11, 823891328731>>) +** (VelocyPack.Error) unexpected byte: <<0xDB>> +``` \ No newline at end of file diff --git a/config/config.exs b/config/config.exs deleted file mode 100644 index 3c50c42..0000000 --- a/config/config.exs +++ /dev/null @@ -1,30 +0,0 @@ -# This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. -use Mix.Config - -# This configuration is loaded before any dependency and is restricted -# to this project. If another project depends on this project, this -# file won't be loaded nor affect the parent project. For this reason, -# if you want to provide default values for your application for -# 3rd-party users, it should be done in your "mix.exs" file. - -# You can configure your application as: -# -# config :velocy_pack, key: :value -# -# and access this configuration in your application as: -# -# Application.get_env(:velocy_pack, :key) -# -# You can also configure a 3rd-party app: -# -# config :logger, level: :info -# - -# It is also possible to import configuration files, relative to this -# directory. For example, you can emulate configuration per environment -# by uncommenting the line below and defining dev.exs, test.exs and such. -# Configuration from the imported file will override the ones defined -# here (which is why it is important to import them last). -# -# import_config "#{Mix.env}.exs" diff --git a/lib/velocy_pack.ex b/lib/velocy_pack.ex index a0b3a69..f27eee6 100644 --- a/lib/velocy_pack.ex +++ b/lib/velocy_pack.ex @@ -1,55 +1,63 @@ defmodule VelocyPack do - @moduledoc """ - An Elixir parser and generator for [VelocyPack](https://github.com/arangodb/velocypack). - """ + @moduledoc File.read!("#{__DIR__}/../README.md") + |> String.split("\n") + |> Enum.drop(2) + |> Enum.join("\n") + + @type vpack :: binary | iodata @doc """ - Parses the VelocyPack value from `input` iodata. + Parses the the first _VelocyPack_ value from a binary or iodata. The options parameter is reserved for future use and not used at the moment. """ - def decode(input, opts \\ []), do: - VelocyPack.Decoder.parse(IO.iodata_to_binary(input), opts) + @spec decode(vpack) :: {:ok, term} | {:ok, {term, vpack}} | {:error, any} + def decode(vpack, opts \\ []) do + __MODULE__.Decoder.parse(IO.iodata_to_binary(vpack), opts) + end @doc """ - Parses the VelocyPack value from `input` iodata. + Parses the the first _VelocyPack_ value from a binary or iodata. - Similar to `decode/2` except it will unwrap the error tuple and raise + Same as `decode/2` except it will unwrap the tuple and raise in case of errors. """ - def decode!(input, opts \\ []) do - case decode(input, opts) do + @spec decode!(vpack) :: term | {term, vpack} + def decode!(vpack, opts \\ []) do + case decode(vpack, opts) do {:ok, value} -> value - {:error, err} -> raise err + {:error, reason} -> raise reason end end @doc """ - Generates VelocyPack corresponding to `input`. + Generates a _VelocyPack_ value as a binary corresponding to `term`. - The generation is controlled by the `VelocyPack.Encoder` protocol, + The generation is controlled by the `Velocy.Encoder` protocol, please refer to the module to read more on how to define the protocol for custom data types. The options parameter is reserved for future use and not used at the moment. """ - def encode(input, opts \\ []) do - case VelocyPack.Encode.encode(input, opts) do - {:ok, result} -> {:ok, IO.iodata_to_binary(result)} - {:error, error} -> {:error, error} + @spec encode(term) :: {:ok, vpack} | {:error, any} + def encode(term, opts \\ []) do + case __MODULE__.Encode.encode(term, opts) do + {:ok, vpack} -> {:ok, IO.iodata_to_binary(vpack)} + {:error, reason} -> {:error, reason} end end @doc """ - Generates VelocyPack corresponding to `input`. + Generates a _VelocyPack_ value as a binary corresponding to `term`. - Similar to `encode/2` except it will unwrap the error tuple and raise + Same as `encode/2` except it will unwrap the tuple and raise in case of errors. """ - def encode!(input, opts \\ []) do - case encode(input, opts) do - {:ok, result} -> result - {:error, error} -> raise error + @spec encode!(term) :: vpack + def encode!(term, opts \\ []) do + case encode(term, opts) do + {:ok, vpack} -> vpack + {:error, reason} -> raise reason end end end diff --git a/lib/velocy_pack/codegen.ex b/lib/velocy_pack/codegen.ex index dd282f9..066f50a 100644 --- a/lib/velocy_pack/codegen.ex +++ b/lib/velocy_pack/codegen.ex @@ -8,16 +8,19 @@ defmodule VelocyPack.Codegen do import Bitwise defmacro __using__(_opts) do - funcs = for i <- 1..4 do - name = "build_index_table_#{1 <<< (i - 1)}" |> String.to_atom - quote do - def unquote(name) ([], acc, _offset), do: IO.iodata_to_binary(acc) - def unquote(name) ([h | tail], acc, offset) do - acc = [<<(h + offset)::unsigned-little-unit(8)-size(power_of_2(unquote(i - 1)))>> | acc] - unquote(name)(tail, acc, offset) + funcs = + for i <- 1..4 do + name = "build_index_table_#{1 <<< (i - 1)}" |> String.to_atom() + + quote do + def unquote(name)([], acc, _offset), do: IO.iodata_to_binary(acc) + + def unquote(name)([h | tail], acc, offset) do + acc = [<> | acc] + unquote(name)(tail, acc, offset) + end end end - end quote do import VelocyPack.Codegen @@ -26,7 +29,7 @@ defmodule VelocyPack.Codegen do end defmacro index_table(offsets, offset, bytes) do - name = "build_index_table_#{bytes}" |> String.to_atom + name = "build_index_table_#{bytes}" |> String.to_atom() quote do: unquote(name)(unquote(offsets), [], unquote(offset)) end @@ -57,6 +60,7 @@ defmodule VelocyPack.Codegen do defp clauses_to_ranges([{:->, _, [[{:in, _, [byte, range]}, rest], action]} | tail], acc) do clauses_to_ranges(tail, [{range, {byte, rest, action}} | acc]) end + defp clauses_to_ranges([{:->, _, [[default, rest], action]} | tail], acc) do {Enum.reverse(acc), {default, rest, action}, literal_clauses(tail)} end @@ -73,6 +77,7 @@ defmodule VelocyPack.Codegen do unquote(action) end ++ jump_table_to_clauses(tail, empty) end + defp jump_table_to_clauses([{val, {byte, rest, action}} | tail], empty) do quote do <> -> @@ -80,6 +85,7 @@ defmodule VelocyPack.Codegen do unquote(action) end ++ jump_table_to_clauses(tail, empty) end + defp jump_table_to_clauses([], literals) do Enum.flat_map(literals, fn {pattern, action} -> quote do @@ -101,6 +107,7 @@ defmodule VelocyPack.Codegen do end) clauses = clauses ++ quote(do: (<<>> -> empty_error(original, skip))) + quote do case unquote(var) do unquote(clauses) @@ -113,6 +120,7 @@ defmodule VelocyPack.Codegen do |> Enum.flat_map(fn {int, value} when is_integer(int) -> [{int, value}] + {{:.., _, [s, e]}, value} when is_integer(s) and is_integer(e) -> Enum.map(s..e, &{&1, value}) end) diff --git a/lib/velocy_pack/decoder.ex b/lib/velocy_pack/decoder.ex index e7594b8..2844a67 100644 --- a/lib/velocy_pack/decoder.ex +++ b/lib/velocy_pack/decoder.ex @@ -4,57 +4,105 @@ defmodule VelocyPack.Decoder do # The implementation of this decoder is heavily inspired by that of Jason (https://github.com/michalmuskala/jason) use Bitwise - alias VelocyPack.Codegen + alias VelocyPack.{Codegen, Error} import Codegen, only: [bytecase: 2] @spec parse(binary(), keyword()) :: {:ok, any()} | {:error, any()} def parse(data, _opts \\ []) when is_binary(data) do try do - {value, <<>>} = value(data) - {:ok, value} + case value(data) do + {value, <<>>} -> + {:ok, value} + + {value, tail} -> + {:ok, {value, tail}} + end + rescue + e in MatchError -> + {:error, Error.exception(e)} + + e in CaseClauseError -> + {:error, Error.exception(e)} catch - err -> - {:error, err} + error -> + {:error, error} end end @spec value(binary()) :: {any(), binary()} defp value(data) do bytecase data do - _ in 0x01, rest -> {[], rest} + _ in 0x01, rest -> + {[], rest} + + type in 0x02..0x05, rest -> + parse_array_without_index_table(type, rest) - type in 0x02..0x05, rest -> parse_array_without_index_table(type, rest) - type in 0x06..0x09, rest -> parse_array_with_index_table(type, rest) + type in 0x06..0x09, rest -> + parse_array_with_index_table(type, rest) - _ in 0x0a, rest -> {%{}, rest} - type in 0x0b..0x0e, rest -> parse_object(type, rest) + _ in 0x0A, rest -> + {%{}, rest} + + type in 0x0B..0x0E, rest -> + parse_object(type, rest) # TODO: 0x0f..0x12 - objects with unsorted index table - _ in 0x13, rest -> parse_compact_array(rest) - _ in 0x14, rest -> parse_compact_object(rest) + _ in 0x13, rest -> + parse_compact_array(rest) + + _ in 0x14, rest -> + parse_compact_object(rest) # 0x15..0x16 - reserved - _ in 0x17, rest -> {:illegal, rest} - _ in 0x18, rest -> {nil, rest} - _ in 0x19, rest -> {false, rest} - _ in 0x1a, rest -> {true, rest} - _ in 0x1b, rest -> parse_double(rest) - _ in 0x1c, rest -> parse_date_time(rest) + _ in 0x17, rest -> + {:illegal, rest} + + _ in 0x18, rest -> + {nil, rest} + + _ in 0x19, rest -> + {false, rest} + + _ in 0x1A, rest -> + {true, rest} + + _ in 0x1B, rest -> + parse_double(rest) + + _ in 0x1C, rest -> + parse_date_time(rest) # 0x1d - external -> not supported - _ in 0x1e, rest -> {:min_key, rest} - _ in 0x1f, rest -> {:max_key, rest} + _ in 0x1E, rest -> + {:min_key, rest} + + _ in 0x1F, rest -> + {:max_key, rest} + + type in 0x20..0x27, rest -> + parse_int(type, rest) + + type in 0x28..0x2F, rest -> + parse_uint(type, rest) - type in 0x20..0x27, rest -> parse_int(type, rest) - type in 0x28..0x2f, rest -> parse_uint(type, rest) - type in 0x30..0x39, rest -> parse_small_int(type, rest) - type in 0x3a..0x3f, rest -> parse_neg_small_int(type, rest) + type in 0x30..0x39, rest -> + parse_small_int(type, rest) - _ in 0x40, rest -> {"", rest} - type in 0x41..0xbe, rest -> parse_short_string(type, rest) - _ in 0xbf, rest -> parse_string(rest) + type in 0x3A..0x3F, rest -> + parse_neg_small_int(type, rest) - type in 0xc0..0xc7, rest -> parse_binary(type, rest) + _ in 0x40, rest -> + {"", rest} + + type in 0x41..0xBE, rest -> + parse_short_string(type, rest) + + _ in 0xBF, rest -> + parse_string(rest) + + type in 0xC0..0xC7, rest -> + parse_binary(type, rest) # 0xc8..0xcf - BCD -> not supported # 0xd0..0xd7 - negative BCD -> not supported @@ -63,32 +111,60 @@ defmodule VelocyPack.Decoder do type, _rest -> error({:unsupported_type, type}) + <<>> -> error(:unexpected_end) end end - defp error(err), do: throw err + defp error(err), do: throw(err) @spec value_size(binary()) :: integer() | no_return() defp value_size(data) do bytecase data do - _ in 0x01, _ -> 1 - type in 0x02..0x09, rest -> get_array_size(type, rest) - _ in 0x0a, _ -> 1 - type in 0x0b..0x0e, rest -> get_object_size(type, rest) - _ in 0x13..0x14, rest -> get_compact_size(rest) + _ in 0x01, _ -> + 1 + + type in 0x02..0x09, rest -> + get_array_size(type, rest) + + _ in 0x0A, _ -> + 1 + + type in 0x0B..0x0E, rest -> + get_object_size(type, rest) + + _ in 0x13..0x14, rest -> + get_compact_size(rest) + # 0x15..0x16 - reserved - _ in 0x17..0x1a, _ -> 1 - _ in 0x1b..0x1c, _ -> 9 + _ in 0x17..0x1A, _ -> + 1 + + _ in 0x1B..0x1C, _ -> + 9 + # 0x1d - external -> not supported - _ in 0x1e..0x1f, _ -> 1 - type in 0x20..0x27, _ -> type - 0x1f + 1 - type in 0x28..0x2f, _ -> type - 0x27 + 1 - _ in 0x30..0x3f, _ -> 1 - type in 0x40..0xbe, _ -> type - 0x40 - _ in 0xbf, rest -> get_string_size(rest) - type in 0xc0..0xc7, rest -> get_binary_size(type, rest) + _ in 0x1E..0x1F, _ -> + 1 + + type in 0x20..0x27, _ -> + type - 0x1F + 1 + + type in 0x28..0x2F, _ -> + type - 0x27 + 1 + + _ in 0x30..0x3F, _ -> + 1 + + type in 0x40..0xBE, _ -> + type - 0x40 + + _ in 0xBF, rest -> + get_string_size(rest) + + type in 0xC0..0xC7, rest -> + get_binary_size(type, rest) # 0xc8..0xcf - BCD -> not supported # 0xd0..0xd7 - negative BCD -> not supported @@ -97,6 +173,7 @@ defmodule VelocyPack.Decoder do type, _rest -> error({:unsupported_type, type}) + <<>> -> error(:unexpected_end) end @@ -110,12 +187,12 @@ defmodule VelocyPack.Decoder do @compile {:inline, parse_date_time: 1} @spec parse_date_time(binary()) :: {any(), binary()} defp parse_date_time(<>), - do: {DateTime.from_unix!(value, :milliseconds), rest} + do: {DateTime.from_unix!(value, :millisecond), rest} @compile {:inline, parse_int: 2} @spec parse_int(integer(), binary()) :: {any(), binary()} defp parse_int(type, data) do - size = type - 0x1f + size = type - 0x1F <> = data {value, rest} end @@ -151,27 +228,31 @@ defmodule VelocyPack.Decoder do {value, rest} end - @spec parse_string( binary()) :: {any(), binary()} - defp parse_string(<>) do + @spec parse_string(binary()) :: {any(), binary()} + defp parse_string( + <> + ) do {value, rest} end @compile {:inline, parse_binary: 2} @spec parse_binary(integer(), binary()) :: {any(), binary()} defp parse_binary(type, data) do - size = type - 0xbf + size = type - 0xBF parse_binary_content(size, data) end @spec parse_binary_content(integer(), binary()) :: {any(), binary()} defp parse_binary_content(size, data) do - <> = data + <> = data + {value, rest} end @spec get_array_size(integer(), binary()) :: integer() defp get_array_size(type, data) do - offset = if (type < 0x06), do: 0x02, else: 0x06 + offset = if type < 0x06, do: 0x02, else: 0x06 size_bytes = 1 <<< (type - offset) <> = data size @@ -179,7 +260,7 @@ defmodule VelocyPack.Decoder do @spec get_object_size(integer(), binary()) :: integer() defp get_object_size(type, data) do - offset = if (type < 0x0e), do: 0x0b, else: 0x0e + offset = if type < 0x0E, do: 0x0B, else: 0x0E size_bytes = 1 <<< (type - offset) <> = data size @@ -187,7 +268,7 @@ defmodule VelocyPack.Decoder do @spec get_binary_size(integer(), binary()) :: integer() defp get_binary_size(type, data) do - size = type - 0xbf + size = type - 0xBF <> = data length end @@ -199,7 +280,8 @@ defmodule VelocyPack.Decoder do end @spec get_string_size(binary()) :: integer() - defp get_string_size(<>), do: length + 8 + 1 + defp get_string_size(<>), + do: length + 8 + 1 @spec parse_array_without_index_table(integer(), binary()) :: {list(), binary()} defp parse_array_without_index_table(type, data) do @@ -209,12 +291,13 @@ defmodule VelocyPack.Decoder do rest = skip_zeros(rest) zeros = data_size - byte_size(rest) elem_size = value_size(rest) - length = div((total_size - size_bytes - 1)- zeros, elem_size) + length = div(total_size - size_bytes - 1 - zeros, elem_size) parse_fixed_size_array_elements(length, elem_size, rest) end @spec parse_fixed_size_array_elements(integer(), integer(), binary()) :: {list(), binary()} defp parse_fixed_size_array_elements(0, _, data), do: {[], data} + defp parse_fixed_size_array_elements(length, elem_size, data) do <> = data {elem, <<>>} = value(elem) @@ -223,27 +306,38 @@ defmodule VelocyPack.Decoder do end @spec parse_array_with_index_table(integer(), binary()) :: {list(), binary()} - defp parse_array_with_index_table(0x09, <>) do - data_size = total_size - 1 - 8 - 8; - <> = rest - { parse_array_with_index_table_elements(length, 8, data), rest} + defp parse_array_with_index_table( + 0x09, + <> + ) do + data_size = total_size - 1 - 8 - 8 + + <> = + rest + + {parse_array_with_index_table_elements(length, 8, data), rest} end + defp parse_array_with_index_table(type, data) do size_bytes = 1 <<< (type - 0x06) + <> = data + length::integer-unsigned-little-unit(8)-size(size_bytes), rest::binary>> = data + data_size = total_size - 1 - 2 * size_bytes <> = rest data = skip_zeros(data) list = parse_array_with_index_table_elements(length, size_bytes, data) - { list, rest } + {list, rest} end @spec parse_array_with_index_table_elements(integer(), integer(), binary()) :: list() defp parse_array_with_index_table_elements(length, size_bytes, data) do - index_table_size = if (length == 1), do: 0, else: length * size_bytes - {list, <<_index_table::binary-size(index_table_size)>>} = parse_variable_size_array_elements(length, data) + index_table_size = if length == 1, do: 0, else: length * size_bytes + + {list, <<_index_table::binary-size(index_table_size)>>} = + parse_variable_size_array_elements(length, data) + list end @@ -259,6 +353,7 @@ defmodule VelocyPack.Decoder do # that this is ~10% faster than a tail-recursive version. @spec parse_variable_size_array_elements(integer(), binary()) :: {list(), binary()} defp parse_variable_size_array_elements(0, data), do: {[], data} + defp parse_variable_size_array_elements(length, data) do {elem, rest} = value(data) {list, rest} = parse_variable_size_array_elements(length - 1, rest) @@ -267,14 +362,18 @@ defmodule VelocyPack.Decoder do @spec parse_object(integer(), binary()) :: {map(), binary()} defp parse_object(type, data) do - size_bytes = 1 <<< (type - 0x0b) + size_bytes = 1 <<< (type - 0x0B) + <> = data + length::integer-unsigned-little-unit(8)-size(size_bytes), rest::binary>> = data + data_size = total_size - 1 - 2 * size_bytes <> = rest - index_table_size = if (length == 1), do: 0, else: length * size_bytes - {obj, <<_index_table::binary-size(index_table_size)>>} = parse_object_members(length, %{}, skip_zeros(data)) + index_table_size = length * size_bytes + + {obj, <<_index_table::binary-size(index_table_size)>>} = + parse_object_members(length, %{}, skip_zeros(data)) + {obj, rest} end @@ -287,6 +386,7 @@ defmodule VelocyPack.Decoder do @spec parse_object_members(integer(), map(), binary()) :: {map(), binary()} defp parse_object_members(0, obj, data), do: {obj, data} + defp parse_object_members(length, obj, data) do {key, rest} = value(data) {value, rest} = value(rest) @@ -318,9 +418,11 @@ defmodule VelocyPack.Decoder do <> = data {v, rest} end - len = len + ((v &&& 0x7f) <<< p) + + len = len + ((v &&& 0x7F) <<< p) p = p + 7 - if ((v &&& 0x80) != 0) do + + if (v &&& 0x80) != 0 do parse_length(rest, len, p, reverse) else {len, rest} diff --git a/lib/velocy_pack/encode.ex b/lib/velocy_pack/encode.ex index 37b606b..fa0aa2f 100644 --- a/lib/velocy_pack/encode.ex +++ b/lib/velocy_pack/encode.ex @@ -1,9 +1,8 @@ defmodule VelocyPack.Encode do - def encode(value, opts \\ []) do try do {v, _size} = value(value, parse_opts(opts)) - {:ok, IO.iodata_to_binary(v)} + {:ok, v} catch err -> {:error, err} end @@ -55,10 +54,11 @@ defmodule VelocyPack.Encode do defp encode_atom(nil), do: {[<<0x18>>], 1} defp encode_atom(false), do: {[<<0x19>>], 1} - defp encode_atom(true), do: {[<<0x1a>>], 1} - defp encode_atom(:min_key), do: {[<<0x1e>>], 1} - defp encode_atom(:max_key), do: {[<<0x1f>>], 1} + defp encode_atom(true), do: {[<<0x1A>>], 1} + defp encode_atom(:min_key), do: {[<<0x1E>>], 1} + defp encode_atom(:max_key), do: {[<<0x1F>>], 1} defp encode_atom(:illegal), do: {[<<0x17>>], 1} + defp encode_atom(value) do value |> Atom.to_string() @@ -73,35 +73,48 @@ defmodule VelocyPack.Encode do defp encode_integer(value) when value in -6..-1, do: {[<<0x40 + value>>], 1} # negative integers - defp encode_integer(value) when value < -power_of_2(63), - do: raise "Cannot encode integers less than #{-power_of_2(63)}." - for i <- 8..1, do: - defp encode_integer(value) when value < -power_of_2(unquote((i - 1) * 8 - 1)), - do: {[<>], unquote(i) + 1} + defp encode_integer(value) when value < -power_of_2(63) do + raise VelocyPack.Error, """ + Cannot encode integers less than #{-power_of_2(63)}.\ + """ + end + + for i <- 8..1 do + defp encode_integer(value) when value < -power_of_2(unquote((i - 1) * 8 - 1)) do + {[<>], unquote(i) + 1} + end + end # positive integers - for i <- 1..8, do: - defp encode_integer(value) when value < power_of_2(unquote(i * 8)), - do: {[<>], unquote(i) + 1} + for i <- 1..8 do + defp encode_integer(value) when value < power_of_2(unquote(i * 8)) do + {[<>], unquote(i) + 1} + end + end + defp encode_integer(_) do - raise "Cannot encode integers greater than #{power_of_2(64) - 1}." + raise VelocyPack.Error, """ + Cannot encode integers greater than #{power_of_2(64) - 1}.\ + """ end # Float - def float(value), do: {[<<0x1b, value::float-little-size(64)>>], 9} + def float(value), do: {[<<0x1B, value::float-little-size(64)>>], 9} # Strings def string(value), do: encode_string(value) defp encode_string(""), do: {[<<0x40>>], 1} + defp encode_string(value) when byte_size(value) <= 126 do - {[<<(byte_size(value) + 0x40), value::binary>>], byte_size(value) + 1} + {[<>], byte_size(value) + 1} end + defp encode_string(value) when is_binary(value) do length = byte_size(value) - {[<<0xbf, length::integer-unsigned-little-size(64), value::binary>>], length + 9} + {[<<0xBF, length::integer-unsigned-little-size(64), value::binary>>], length + 9} end # Lists @@ -109,29 +122,36 @@ defmodule VelocyPack.Encode do def list(value, opts), do: encode_list(value, opts) defp encode_list([], _), do: {[<<0x01>>], 1} - defp encode_list(value, {true, _} = opts) do # compact array - {iodata, total_size, count} = value |> Enum.reduce({[], 0, 0}, - fn (v, {acc, total_size, count}) -> + # compact array + defp encode_list(value, {true, _} = opts) do + {iodata, total_size, count} = + Enum.reduce(value, {[], 0, 0}, fn v, {acc, total_size, count} -> {v, size} = value(v, opts) {[v | acc], total_size + size, count + 1} end) + iodata = :lists.reverse(iodata) iodata = if count >= 1000, do: IO.iodata_to_binary(iodata), else: iodata encode_compact_data(<<0x13>>, iodata, total_size, count) end + defp encode_list([head | tail], opts) do # Use a singe pass to calculate the offsets, the total size, the number of elements # and whether all elements have the same size. {head, head_size} = value(head, opts) + {iodata, offsets, total_size, count, equal_sizes} = - tail - |> Enum.reduce({[head], [0], head_size, 1, true}, - fn (v, {acc, offsets, total_size, count, equal_sizes}) -> + Enum.reduce( + tail, + {[head], [0], head_size, 1, true}, + fn v, {acc, offsets, total_size, count, equal_sizes} -> {v, size} = value(v, opts) equal_sizes = equal_sizes && size == head_size {[v | acc], [total_size | offsets], total_size + size, count + 1, equal_sizes} - end) + end + ) + iodata = :lists.reverse(iodata) # NOTE: we do not reverse the offsets list, because this is done @@ -140,6 +160,7 @@ defmodule VelocyPack.Encode do # Tests showed that for large lists it is significantly faster # to immediately convert the data to binary. iodata = if count >= 1000, do: IO.iodata_to_binary(iodata), else: iodata + cond do equal_sizes -> # all elements have the same size -> create an array without index table @@ -151,9 +172,16 @@ defmodule VelocyPack.Encode do end for i <- 1..4 do - defp encode_list_without_index_table(iodata, total_size) when total_size < power_of_2(unquote(i * 8)) do + defp encode_list_without_index_table(iodata, total_size) + when total_size < power_of_2(unquote(i * 8)) do total_size = total_size + 1 + power_of_2(unquote(i - 1)) - {[<> | iodata], total_size} + + header = << + unquote(0x01 + i), + total_size::integer-unsigned-little-unit(8)-size(power_of_2(unquote(i - 1))) + >> + + {[header | iodata], total_size} end end @@ -161,19 +189,27 @@ defmodule VelocyPack.Encode do cond do count < power_of_2(8) and total_size + count + 3 < power_of_2(8) -> total_size = total_size + count + 3 - {[<<0x06, total_size::unsigned-size(8), count::unsigned-size(8)>>, iodata, index_table(offsets, 3, 1)], total_size} + header = <<0x06, total_size::unsigned-size(8), count::unsigned-size(8)>> + + {[header, iodata, index_table(offsets, 3, 1)], total_size} count < power_of_2(16) and total_size + count * 2 + 5 < power_of_2(16) -> total_size = total_size + count * 2 + 5 - {[<<0x07, total_size::unsigned-little-size(16), count::unsigned-little-size(16)>>, iodata, index_table(offsets, 5, 2)], total_size} + header = <<0x07, total_size::unsigned-little-size(16), count::unsigned-little-size(16)>> + + {[header, iodata, index_table(offsets, 5, 2)], total_size} count < power_of_2(32) and total_size + count * 4 + 9 < power_of_2(32) -> total_size = total_size + count * 4 + 9 - {[<<0x08, total_size::unsigned-little-size(32), count::unsigned-little-size(32)>>, iodata, index_table(offsets, 9, 4)], total_size} + header = <<0x08, total_size::unsigned-little-size(32), count::unsigned-little-size(32)>> + + {[header, iodata, index_table(offsets, 9, 4)], total_size} true -> total_size = total_size + count * 8 + 17 - {[<<0x09, total_size::unsigned-little-size(64), count::unsigned-little-size(64)>>, iodata, index_table(offsets, 17, 8)], total_size} + header = <<0x09, total_size::unsigned-little-size(64), count::unsigned-little-size(64)>> + + {[header, iodata, index_table(offsets, 17, 8)], total_size} end end @@ -181,34 +217,42 @@ defmodule VelocyPack.Encode do def map(value, opts), do: encode_map(value, opts) - defp encode_map(value, _) when value === %{} , do: {[<<0x0a>>], 1} - defp encode_map(value, {_, true} = opts) do # compact object + defp encode_map(value, _) when value === %{}, do: {[<<0x0A>>], 1} + # compact object + defp encode_map(value, {_, true} = opts) do {iodata, total_size, count} = - value - |> Enum.reduce({[], 0, 0}, - fn ({k, v}, {acc, total_size, count}) -> + Enum.reduce( + value, + {[], 0, 0}, + fn {k, v}, {acc, total_size, count} -> {key, key_size} = encode_string(as_key(k)) {val, val_size} = value(v, opts) size = key_size + val_size {[val, key | acc], total_size + size, count + 1} - end) + end + ) + iodata = :lists.reverse(iodata) iodata = if count >= 1000, do: IO.iodata_to_binary(iodata), else: iodata encode_compact_data(<<0x14>>, iodata, total_size, count) end + defp encode_map(value, opts) do {iodata, offsets, total_size, count} = value |> Enum.map(fn {k, v} -> {as_key(k), v} end) |> Enum.sort() - |> Enum.reduce({[], [], 0, 0}, - fn ({k, v}, {acc, offsets, total_size, count}) -> + |> Enum.reduce( + {[], [], 0, 0}, + fn {k, v}, {acc, offsets, total_size, count} -> {key, key_size} = encode_string(k) {val, val_size} = value(v, opts) size = key_size + val_size {[val, key | acc], [total_size | offsets], total_size + size, count + 1} - end) + end + ) + iodata = :lists.reverse(iodata) # NOTE: we do not reverse the offsets list, because this is done @@ -220,31 +264,41 @@ defmodule VelocyPack.Encode do defp encode_map_with_index_table(iodata, count, offsets, total_size) do cond do - count == 1 and total_size + 3 < power_of_2(8) -> - total_size = total_size + 3 - {[<<0x0b, total_size::unsigned-size(8), 1::unsigned-size(8)>> | iodata], total_size} - count < power_of_2(8) and total_size + count + 3 < power_of_2(8) -> total_size = total_size + count + 3 - {[<<0x0b, total_size::unsigned-size(8), count::unsigned-size(8)>>, iodata, index_table(offsets, 3, 1)], total_size} + header = <<0x0B, total_size::unsigned-size(8), count::unsigned-size(8)>> + + {[header, iodata, index_table(offsets, 3, 1)], total_size} count < power_of_2(16) and total_size + count * 2 + 5 < power_of_2(16) -> total_size = total_size + count * 2 + 5 - {[<<0x0c, total_size::unsigned-little-size(16), count::unsigned-little-size(16)>>, iodata, index_table(offsets, 5, 2)], total_size} + header = <<0x0C, total_size::unsigned-little-size(16), count::unsigned-little-size(16)>> + + {[header, iodata, index_table(offsets, 5, 2)], total_size} count < power_of_2(32) and total_size + count * 4 + 9 < power_of_2(32) -> total_size = total_size + count * 4 + 9 - {[<<0x0d, total_size::unsigned-little-size(32), count::unsigned-little-size(32)>>, iodata, index_table(offsets, 9, 4)], total_size} + header = <<0x0D, total_size::unsigned-little-size(32), count::unsigned-little-size(32)>> + + {[header, iodata, index_table(offsets, 9, 4)], total_size} true -> total_size = total_size + count * 8 + 17 - {[<<0x0e, total_size::unsigned-little-size(64)>>, iodata, index_table(offsets, 9, 8), <>], total_size} + header = <<0x0E, total_size::unsigned-little-size(64)>> + + {[header, iodata, index_table(offsets, 9, 8), <>], + total_size} end end defp as_key(value) when is_atom(value), do: Atom.to_string(value) defp as_key(value) when is_binary(value), do: value - defp as_key(value), do: raise "Invalid key '#{inspect value}' - keys have to be atoms or strings." + + defp as_key(value) do + raise VelocyPack.Error, """ + Invalid key '#{inspect(value)}' - keys have to be atoms or strings.\ + """ + end use Bitwise @@ -258,26 +312,30 @@ defmodule VelocyPack.Encode do defp compact_size(size) do bytes = calc_compact_bytes(size) final_size = size + bytes - final_size = if bytes == calc_compact_bytes(final_size) do - final_size - else - # Due to the number of bytes required for the size information itself - # we need an additional byte to encode the final total size. - final_size + 1 - end + + final_size = + if bytes == calc_compact_bytes(final_size) do + final_size + else + # Due to the number of bytes required for the size information itself + # we need an additional byte to encode the final total size. + final_size + 1 + end + {compact_integer(final_size, false), final_size} end defp compact_integer(value, reverse) do v = compact_integer(value) - if (reverse), do: :lists.reverse(v), else: v + if reverse, do: :lists.reverse(v), else: v end defp compact_integer(value) when value < power_of_2(7) do [<>] end + defp compact_integer(value) do - v = (value &&& 0x7f) ||| (1 <<< 7) + v = (value &&& 0x7F) ||| 1 <<< 7 value = value >>> 7 [<> | compact_integer(value)] end diff --git a/lib/velocy_pack/encoder.ex b/lib/velocy_pack/encoder.ex index 933254a..8bfd5ee 100644 --- a/lib/velocy_pack/encoder.ex +++ b/lib/velocy_pack/encoder.ex @@ -1,6 +1,6 @@ defprotocol VelocyPack.Encoder do @moduledoc """ - Protocol controlling how a value is encoded to VelocyPack. + Protocol controlling how a value is encoded to _VelocyPack_. """ def encode(value, opts) diff --git a/lib/velocy_pack/error.ex b/lib/velocy_pack/error.ex new file mode 100644 index 0000000..84c477c --- /dev/null +++ b/lib/velocy_pack/error.ex @@ -0,0 +1,30 @@ +defmodule VelocyPack.Error do + defexception [:dump, message: "velocy_pack error"] + + def exception(%MatchError{term: ""}) do + %__MODULE__{message: "unexpected sequence", dump: nil} + end + + def exception(%CaseClauseError{term: ""}) do + %__MODULE__{message: "unexpected sequence", dump: nil} + end + + def exception(%MatchError{term: bytes}) do + %__MODULE__{message: "unexpected byte", dump: dump(bytes)} + end + + def exception(%CaseClauseError{term: bytes}) do + %__MODULE__{message: "unexpected byte", dump: dump(bytes)} + end + + def exception(message), do: %__MODULE__{message: message} + + def message(%__MODULE__{message: message, dump: nil}), do: message + + def message(%__MODULE__{message: message, dump: ""}), do: message + + def message(%__MODULE__{message: message, dump: dump}), do: "#{message}: #{dump}" + + defp dump(bytes) when is_binary(bytes), do: inspect(bytes, base: :hex) + defp dump(_bytes), do: "not a binary" +end diff --git a/mix.exs b/mix.exs index 185bf1d..480679c 100644 --- a/mix.exs +++ b/mix.exs @@ -1,29 +1,54 @@ -defmodule VelocyPack.Mixfile do +defmodule VelocyPack.MixProject do use Mix.Project + @version "0.1.1" + @description """ + An Elixir parser and generator for VelocyPack v1. + """ + @source_url "https://github.com/ArangoDB-Community/velocy_pack" + @homepage_url "https://github.com/arangodb/velocypack/blob/master/VelocyPack.md" + def project do [ - app: :velocy_pack, - version: "0.1.0", + app: :velocy, + version: @version, elixir: "~> 1.5", - start_permanent: Mix.env == :prod, + start_permanent: Mix.env() == :prod, + name: "VelocyPack", + description: @description, + source_url: @source_url, + homepage_url: @homepage_url, + package: package(), + docs: docs(), deps: deps() ] end # Run "mix help compile.app" to learn about applications. def application do + [] + end + + defp package do + [ + licenses: ["Apache-2.0"], + links: %{"GitHub" => @source_url} + ] + end + + defp docs do [ - extra_applications: [:logger] + source_ref: "v#{@version}", + main: "readme", + extras: ["README.md"] ] end # Run "mix help deps" to learn about dependencies. defp deps do [ - # {:dep_from_hexpm, "~> 0.3.0"}, - # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, - {:dialyxir, "~> 0.5", only: [:dev], runtime: false} + {:dialyxir, "~> 0.5", only: :dev, runtime: false}, + {:ex_doc, "> 0.0.0", only: :dev, runtime: false} ] end end diff --git a/mix.lock b/mix.lock index fa0b5ce..215f903 100644 --- a/mix.lock +++ b/mix.lock @@ -1 +1,8 @@ -%{"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}} +%{ + "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, + "earmark": {:hex, :earmark, "1.4.1", "07bb382826ee8d08d575a1981f971ed41bd5d7e86b917fd012a93c51b5d28727", [:mix], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, +} diff --git a/test/decoder_test.exs b/test/decoder_test.exs index 02fd6db..ef4db8a 100644 --- a/test/decoder_test.exs +++ b/test/decoder_test.exs @@ -1,6 +1,5 @@ defmodule VelocyPack.DecoderTest do - use ExUnit.Case - doctest VelocyPack + use ExUnit.Case, async: true import VelocyPack @@ -10,7 +9,7 @@ defmodule VelocyPack.DecoderTest do end test "empty object" do - assert decode!(<<0x0a>>) == %{} + assert decode!(<<0x0A>>) == %{} end test "illegal" do @@ -23,140 +22,170 @@ defmodule VelocyPack.DecoderTest do test "boolean" do assert decode!(<<0x19>>) == false - assert decode!(<<0x1a>>) == true + assert decode!(<<0x1A>>) == true end test "double" do - assert decode!(<<0x1b, 0x66, 0x66, 0x66, 0x66, 0x66, 0xb6, 0x60, 0x40>>) == 133.7; - assert decode!(<<0x1b, 0x66, 0x66, 0x66, 0x66, 0x66, 0xb6, 0x60, 0xc0>>) == -133.7; + assert decode!(<<0x1B, 0x66, 0x66, 0x66, 0x66, 0x66, 0xB6, 0x60, 0x40>>) == 133.7 + assert decode!(<<0x1B, 0x66, 0x66, 0x66, 0x66, 0x66, 0xB6, 0x60, 0xC0>>) == -133.7 end test "date" do - assert decode!(<<0x1c, 0, 83, 115, 5, -114, 0, 0, 0>>) == DateTime.from_unix!(609976800000, :milliseconds) + assert decode!(<<0x1C, 0, 83, 115, 5, -114, 0, 0, 0>>) == + DateTime.from_unix!(609_976_800_000, :millisecond) end test "min/max key" do - assert decode!(<<0x1e>>) == :min_key - assert decode!(<<0x1f>>) == :max_key + assert decode!(<<0x1E>>) == :min_key + assert decode!(<<0x1F>>) == :max_key end test "small int" do - assert decode!(<<0x30>>) == 0 - assert decode!(<<0x31>>) == 1 - assert decode!(<<0x32>>) == 2 - assert decode!(<<0x33>>) == 3 - assert decode!(<<0x34>>) == 4 - assert decode!(<<0x35>>) == 5 - assert decode!(<<0x36>>) == 6 - assert decode!(<<0x37>>) == 7 - assert decode!(<<0x38>>) == 8 - assert decode!(<<0x39>>) == 9 - assert decode!(<<0x3a>>) == -6 - assert decode!(<<0x3b>>) == -5 - assert decode!(<<0x3c>>) == -4 - assert decode!(<<0x3d>>) == -3 - assert decode!(<<0x3e>>) == -2 - assert decode!(<<0x3f>>) == -1 + assert decode!(<<0x30>>) == 0 + assert decode!(<<0x31>>) == 1 + assert decode!(<<0x32>>) == 2 + assert decode!(<<0x33>>) == 3 + assert decode!(<<0x34>>) == 4 + assert decode!(<<0x35>>) == 5 + assert decode!(<<0x36>>) == 6 + assert decode!(<<0x37>>) == 7 + assert decode!(<<0x38>>) == 8 + assert decode!(<<0x39>>) == 9 + assert decode!(<<0x3A>>) == -6 + assert decode!(<<0x3B>>) == -5 + assert decode!(<<0x3C>>) == -4 + assert decode!(<<0x3D>>) == -3 + assert decode!(<<0x3E>>) == -2 + assert decode!(<<0x3F>>) == -1 end test "int" do - assert decode!(<<0x20, 0xff>>) == -1 - assert decode!(<<0x20, 0x7f>>) == 127 + assert decode!(<<0x20, 0xFF>>) == -1 + assert decode!(<<0x20, 0x7F>>) == 127 assert decode!(<<0x20, 0x80>>) == -128 - assert decode!(<<0x21, 0xff, 0xff>>) == -1 - assert decode!(<<0x22, 0xff, 0xff, 0xff>>) == -1 - assert decode!(<<0x23, 0xff, 0xff, 0xff, 0xff>>) == -1 - assert decode!(<<0x24, 0xff, 0xff, 0xff, 0xff, 0xff>>) == -1 - assert decode!(<<0x25, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>>) == -1 - assert decode!(<<0x26, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>>) == -1 - assert decode!(<<0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>>) == -1 - assert decode!(<<0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f>>) == 9223372036854775807 - assert decode!(<<0x28, 0xff>>) == 255 - assert decode!(<<0x29, 0xff, 0xff>>) == 65535 - assert decode!(<<0x2a, 0xff, 0xff, 0xff>>) == 16777215 - assert decode!(<<0x2b, 0xff, 0xff, 0xff, 0xff>>) == 4294967295 - assert decode!(<<0x2c, 0xff, 0xff, 0xff, 0xff, 0xff>>) == 1099511627775 - assert decode!(<<0x2d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>>) == 281474976710655 - assert decode!(<<0x2e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>>) == 72057594037927935 - assert decode!(<<0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>>) == 18446744073709551615 + assert decode!(<<0x21, 0xFF, 0xFF>>) == -1 + assert decode!(<<0x22, 0xFF, 0xFF, 0xFF>>) == -1 + assert decode!(<<0x23, 0xFF, 0xFF, 0xFF, 0xFF>>) == -1 + assert decode!(<<0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == -1 + assert decode!(<<0x25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == -1 + assert decode!(<<0x26, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == -1 + assert decode!(<<0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == -1 + + assert decode!(<<0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F>>) == + 9_223_372_036_854_775_807 + + assert decode!(<<0x28, 0xFF>>) == 255 + assert decode!(<<0x29, 0xFF, 0xFF>>) == 65535 + assert decode!(<<0x2A, 0xFF, 0xFF, 0xFF>>) == 16_777_215 + assert decode!(<<0x2B, 0xFF, 0xFF, 0xFF, 0xFF>>) == 4_294_967_295 + assert decode!(<<0x2C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == 1_099_511_627_775 + assert decode!(<<0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == 281_474_976_710_655 + assert decode!(<<0x2E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == 72_057_594_037_927_935 + + assert decode!(<<0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>>) == + 18_446_744_073_709_551_615 end test "short string" do - assert decode!(<<0x4b, 72, 97, 108, 108, 111, 32, 87, 101, 108, 116, 33>>) == "Hallo Welt!" - assert decode!(<<0x4c, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33>>) == "Hello World!" + assert decode!(<<0x4B, 72, 97, 108, 108, 111, 32, 87, 101, 108, 116, 33>>) == "Hallo Welt!" + + assert decode!(<<0x4C, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33>>) == + "Hello World!" end test "string" do - expected = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. " - <> "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " - <> "Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. " - <> "Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, " - <> "venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. " - <> "Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." - data = << - 0xbf, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6f, 0x72, 0x65, 0x6d, - 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, - 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, - 0x75, 0x65, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x65, - 0x6c, 0x69, 0x74, 0x2e, 0x20, 0x41, 0x65, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x64, 0x6f, 0x20, 0x6c, 0x69, 0x67, 0x75, 0x6c, 0x61, 0x20, 0x65, 0x67, 0x65, 0x74, 0x20, - 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x20, 0x41, 0x65, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6d, 0x61, - 0x73, 0x73, 0x61, 0x2e, 0x20, 0x43, 0x75, 0x6d, 0x20, 0x73, 0x6f, 0x63, 0x69, 0x69, 0x73, 0x20, - 0x6e, 0x61, 0x74, 0x6f, 0x71, 0x75, 0x65, 0x20, 0x70, 0x65, 0x6e, 0x61, 0x74, 0x69, 0x62, 0x75, - 0x73, 0x20, 0x65, 0x74, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x20, - 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x6f, 0x6e, 0x74, 0x65, - 0x73, 0x2c, 0x20, 0x6e, 0x61, 0x73, 0x63, 0x65, 0x74, 0x75, 0x72, 0x20, 0x72, 0x69, 0x64, 0x69, - 0x63, 0x75, 0x6c, 0x75, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x2e, 0x20, 0x44, 0x6f, 0x6e, 0x65, 0x63, - 0x20, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x66, 0x65, 0x6c, 0x69, 0x73, 0x2c, 0x20, 0x75, 0x6c, 0x74, - 0x72, 0x69, 0x63, 0x69, 0x65, 0x73, 0x20, 0x6e, 0x65, 0x63, 0x2c, 0x20, 0x70, 0x65, 0x6c, 0x6c, - 0x65, 0x6e, 0x74, 0x65, 0x73, 0x71, 0x75, 0x65, 0x20, 0x65, 0x75, 0x2c, 0x20, 0x70, 0x72, 0x65, - 0x74, 0x69, 0x75, 0x6d, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2c, 0x20, 0x73, 0x65, 0x6d, 0x2e, 0x20, - 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61, 0x74, 0x20, - 0x6d, 0x61, 0x73, 0x73, 0x61, 0x20, 0x71, 0x75, 0x69, 0x73, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x2e, - 0x20, 0x44, 0x6f, 0x6e, 0x65, 0x63, 0x20, 0x70, 0x65, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x73, 0x74, - 0x6f, 0x2c, 0x20, 0x66, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x6c, 0x6c, 0x61, 0x20, 0x76, 0x65, 0x6c, - 0x2c, 0x20, 0x61, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x74, 0x20, 0x6e, 0x65, 0x63, 0x2c, 0x20, 0x76, - 0x75, 0x6c, 0x70, 0x75, 0x74, 0x61, 0x74, 0x65, 0x20, 0x65, 0x67, 0x65, 0x74, 0x2c, 0x20, 0x61, - 0x72, 0x63, 0x75, 0x2e, 0x20, 0x49, 0x6e, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20, 0x6a, 0x75, 0x73, - 0x74, 0x6f, 0x2c, 0x20, 0x72, 0x68, 0x6f, 0x6e, 0x63, 0x75, 0x73, 0x20, 0x75, 0x74, 0x2c, 0x20, - 0x69, 0x6d, 0x70, 0x65, 0x72, 0x64, 0x69, 0x65, 0x74, 0x20, 0x61, 0x2c, 0x20, 0x76, 0x65, 0x6e, - 0x65, 0x6e, 0x61, 0x74, 0x69, 0x73, 0x20, 0x76, 0x69, 0x74, 0x61, 0x65, 0x2c, 0x20, 0x6a, 0x75, - 0x73, 0x74, 0x6f, 0x2e, 0x20, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x6d, 0x20, 0x64, 0x69, 0x63, 0x74, - 0x75, 0x6d, 0x20, 0x66, 0x65, 0x6c, 0x69, 0x73, 0x20, 0x65, 0x75, 0x20, 0x70, 0x65, 0x64, 0x65, - 0x20, 0x6d, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x74, 0x69, 0x75, 0x6d, 0x2e, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x75, - 0x6e, 0x74, 0x2e, 0x20, 0x43, 0x72, 0x61, 0x73, 0x20, 0x64, 0x61, 0x70, 0x69, 0x62, 0x75, 0x73, - 0x2e, 0x20, 0x56, 0x69, 0x76, 0x61, 0x6d, 0x75, 0x73, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x75, 0x6d, 0x20, 0x73, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x20, 0x6e, 0x69, 0x73, 0x69, 0x2e, - 0x20, 0x41, 0x65, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x76, 0x75, 0x6c, 0x70, 0x75, 0x74, 0x61, 0x74, - 0x65, 0x20, 0x65, 0x6c, 0x65, 0x69, 0x66, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x65, 0x6c, 0x6c, 0x75, - 0x73, 0x2e>> + expected = + "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. " <> + "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " <> + "Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. " <> + "Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, " <> + "venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. " <> + "Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." + + data = + <<0xBF, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x6F, 0x72, 0x65, 0x6D, + 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, + 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, + 0x63, 0x74, 0x65, 0x74, 0x75, 0x65, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, + 0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20, 0x41, 0x65, 0x6E, + 0x65, 0x61, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x6C, 0x69, + 0x67, 0x75, 0x6C, 0x61, 0x20, 0x65, 0x67, 0x65, 0x74, 0x20, 0x64, 0x6F, 0x6C, 0x6F, + 0x72, 0x2E, 0x20, 0x41, 0x65, 0x6E, 0x65, 0x61, 0x6E, 0x20, 0x6D, 0x61, 0x73, 0x73, + 0x61, 0x2E, 0x20, 0x43, 0x75, 0x6D, 0x20, 0x73, 0x6F, 0x63, 0x69, 0x69, 0x73, 0x20, + 0x6E, 0x61, 0x74, 0x6F, 0x71, 0x75, 0x65, 0x20, 0x70, 0x65, 0x6E, 0x61, 0x74, 0x69, + 0x62, 0x75, 0x73, 0x20, 0x65, 0x74, 0x20, 0x6D, 0x61, 0x67, 0x6E, 0x69, 0x73, 0x20, + 0x64, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x69, 0x65, 0x6E, 0x74, + 0x20, 0x6D, 0x6F, 0x6E, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x6E, 0x61, 0x73, 0x63, 0x65, + 0x74, 0x75, 0x72, 0x20, 0x72, 0x69, 0x64, 0x69, 0x63, 0x75, 0x6C, 0x75, 0x73, 0x20, + 0x6D, 0x75, 0x73, 0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20, 0x71, 0x75, 0x61, + 0x6D, 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x2C, 0x20, 0x75, 0x6C, 0x74, 0x72, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x20, 0x6E, 0x65, 0x63, 0x2C, 0x20, 0x70, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x74, 0x65, 0x73, 0x71, 0x75, 0x65, 0x20, 0x65, 0x75, 0x2C, 0x20, 0x70, + 0x72, 0x65, 0x74, 0x69, 0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20, 0x73, + 0x65, 0x6D, 0x2E, 0x20, 0x4E, 0x75, 0x6C, 0x6C, 0x61, 0x20, 0x63, 0x6F, 0x6E, 0x73, + 0x65, 0x71, 0x75, 0x61, 0x74, 0x20, 0x6D, 0x61, 0x73, 0x73, 0x61, 0x20, 0x71, 0x75, + 0x69, 0x73, 0x20, 0x65, 0x6E, 0x69, 0x6D, 0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, + 0x20, 0x70, 0x65, 0x64, 0x65, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x2C, 0x20, 0x66, + 0x72, 0x69, 0x6E, 0x67, 0x69, 0x6C, 0x6C, 0x61, 0x20, 0x76, 0x65, 0x6C, 0x2C, 0x20, + 0x61, 0x6C, 0x69, 0x71, 0x75, 0x65, 0x74, 0x20, 0x6E, 0x65, 0x63, 0x2C, 0x20, 0x76, + 0x75, 0x6C, 0x70, 0x75, 0x74, 0x61, 0x74, 0x65, 0x20, 0x65, 0x67, 0x65, 0x74, 0x2C, + 0x20, 0x61, 0x72, 0x63, 0x75, 0x2E, 0x20, 0x49, 0x6E, 0x20, 0x65, 0x6E, 0x69, 0x6D, + 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x2C, 0x20, 0x72, 0x68, 0x6F, 0x6E, 0x63, 0x75, + 0x73, 0x20, 0x75, 0x74, 0x2C, 0x20, 0x69, 0x6D, 0x70, 0x65, 0x72, 0x64, 0x69, 0x65, + 0x74, 0x20, 0x61, 0x2C, 0x20, 0x76, 0x65, 0x6E, 0x65, 0x6E, 0x61, 0x74, 0x69, 0x73, + 0x20, 0x76, 0x69, 0x74, 0x61, 0x65, 0x2C, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x2E, + 0x20, 0x4E, 0x75, 0x6C, 0x6C, 0x61, 0x6D, 0x20, 0x64, 0x69, 0x63, 0x74, 0x75, 0x6D, + 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x20, 0x65, 0x75, 0x20, 0x70, 0x65, 0x64, 0x65, + 0x20, 0x6D, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x74, 0x69, 0x75, + 0x6D, 0x2E, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6E, + 0x63, 0x69, 0x64, 0x75, 0x6E, 0x74, 0x2E, 0x20, 0x43, 0x72, 0x61, 0x73, 0x20, 0x64, + 0x61, 0x70, 0x69, 0x62, 0x75, 0x73, 0x2E, 0x20, 0x56, 0x69, 0x76, 0x61, 0x6D, 0x75, + 0x73, 0x20, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x73, 0x65, + 0x6D, 0x70, 0x65, 0x72, 0x20, 0x6E, 0x69, 0x73, 0x69, 0x2E, 0x20, 0x41, 0x65, 0x6E, + 0x65, 0x61, 0x6E, 0x20, 0x76, 0x75, 0x6C, 0x70, 0x75, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x65, 0x6C, 0x65, 0x69, 0x66, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x65, 0x6C, 0x6C, 0x75, + 0x73, 0x2E>> + assert decode!(data) == expected end test "binary" do expected = <<49, 50, 51, 52, 53, 54, 55, 56, 57>> - assert decode!(<<0xc0, 9, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc1, 9, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc2, 9, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc3, 9, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc4, 9, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc5, 9, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc6, 9, 0, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected - assert decode!(<<0xc7, 9, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + assert decode!(<<0xC0, 9, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + assert decode!(<<0xC1, 9, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + assert decode!(<<0xC2, 9, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + assert decode!(<<0xC3, 9, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + assert decode!(<<0xC4, 9, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + assert decode!(<<0xC5, 9, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == expected + + assert decode!(<<0xC6, 9, 0, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == + expected + + assert decode!(<<0xC7, 9, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>) == + expected end test "array with index table" do - expected = [ 1, 2, 3 ]; + expected = [1, 2, 3] assert decode!(<<0x06, 0x09, 0x03, 0x31, 0x32, 0x33, 0x03, 0x04, 0x05>>) == expected - assert decode!(<<0x06, 0x0a, 0x03, 0x00, 0x31, 0x32, 0x33, 0x03, 0x04, 0x05>>) == expected - - assert decode!(<<0x07, 0x0e, 0x00, 0x03, 0x00, 0x31, 0x32, 0x33, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00>>) == expected - assert decode!(<<0x08, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x09, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00>>) == expected - assert decode!(<<0x09, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>>) == expected + assert decode!(<<0x06, 0x0A, 0x03, 0x00, 0x31, 0x32, 0x33, 0x03, 0x04, 0x05>>) == expected + + assert decode!( + <<0x07, 0x0E, 0x00, 0x03, 0x00, 0x31, 0x32, 0x33, 0x05, 0x00, 0x06, 0x00, 0x07, + 0x00>> + ) == expected + + assert decode!( + <<0x08, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x09, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00>> + ) == expected + + assert decode!( + <<0x09, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00>> + ) == expected end test "array with index table with single element" do @@ -164,15 +193,20 @@ defmodule VelocyPack.DecoderTest do end test "array without index table" do - expected = [ 1, 2, 3 ]; + expected = [1, 2, 3] assert decode!(<<0x02, 0x05, 0x31, 0x32, 0x33>>) == expected assert decode!(<<0x02, 0x06, 0x00, 0x31, 0x32, 0x33>>) == expected assert decode!(<<0x03, 0x06, 0x00, 0x31, 0x32, 0x33>>) == expected assert decode!(<<0x04, 0x08, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33>>) == expected - assert decode!(<<0x05, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33>>) == expected - assert decode!(<<0x02, 0x0b, 0x1b, 00::little-unsigned-size(64)>>) == [0.0] - assert decode!(<<0x02, 0x0b, 0x1c, 00::little-unsigned-size(64)>>) == [DateTime.from_unix!(0, :milliseconds)] + assert decode!(<<0x05, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33>>) == + expected + + assert decode!(<<0x02, 0x0B, 0x1B, 00::little-unsigned-size(64)>>) == [0.0] + + assert decode!(<<0x02, 0x0B, 0x1C, 00::little-unsigned-size(64)>>) == [ + DateTime.from_unix!(0, :millisecond) + ] end test "compact array" do @@ -181,148 +215,332 @@ defmodule VelocyPack.DecoderTest do test "nested arrays" do expected = [[1, 2, 3], [1, 2, 3]] - assert decode!(<<0x02, 0x0c, 0x02, 0x05, 0x31, 0x32, 0x33, 0x02, 0x05, 0x31, 0x32, 0x33>>) == expected + + assert decode!(<<0x02, 0x0C, 0x02, 0x05, 0x31, 0x32, 0x33, 0x02, 0x05, 0x31, 0x32, 0x33>>) == + expected end test "array with nested compact array" do - expected = [[1, 2, 3], [1, 2, 3 ]] - assert decode!(<<0x02, 0x0e, 0x13, 0x06, 0x31, 0x32, 0x33, 0x03, 0x13, 0x06, 0x31, 0x32, 0x33, 0x03>>) == expected + expected = [[1, 2, 3], [1, 2, 3]] + + assert decode!( + <<0x02, 0x0E, 0x13, 0x06, 0x31, 0x32, 0x33, 0x03, 0x13, 0x06, 0x31, 0x32, 0x33, + 0x03>> + ) == expected end test "object with single string entry" do - expected = %{ "a" => "b" } - assert decode!(<<0x0b, 0x07, 0x01, 0x41, 0x61, 0x41, 0x62>>) == expected + expected = %{"a" => "b"} + assert decode!(<<0x0B, 0x08, 0x01, 0x41, 0x61, 0x41, 0x62, 0x03>>) == expected end test "compact object" do expected = %{"a" => 12, "b" => true, "c" => "xyz"} - assert decode!(<<0x14, 0x10, 0x41, 0x61, 0x28, 0x0c, 0x41, 0x62, 0x1a, 0x41, 0x63, 0x43, 0x78, 0x79, - 0x7a, 0x03>>) == expected + + assert decode!( + <<0x14, 0x10, 0x41, 0x61, 0x28, 0x0C, 0x41, 0x62, 0x1A, 0x41, 0x63, 0x43, 0x78, + 0x79, 0x7A, 0x03>> + ) == expected end test "array of objects" do - expected = [%{"a" => 12, "b" => true, "c" => "xyz"}, %{"a" => 12, "b" => true, "c" => "xyz"}] - assert decode!(<<0x13, 0x23, 0x14, 0x10, 0x41, 0x61, 0x28, 0x0c, 0x41, 0x62, 0x1a, 0x41, 0x63, 0x43, 0x78, 0x79, - 0x7a, 0x03, 0x14, 0x10, 0x41, 0x61, 0x28, 0x0c, 0x41, 0x62, 0x1a, 0x41, 0x63, 0x43, 0x78, 0x79, - 0x7a, 0x03, 0x02>>) == expected + expected = [ + %{"a" => 12, "b" => true, "c" => "xyz"}, + %{"a" => 12, "b" => true, "c" => "xyz"} + ] + + assert decode!( + <<0x13, 0x23, 0x14, 0x10, 0x41, 0x61, 0x28, 0x0C, 0x41, 0x62, 0x1A, 0x41, 0x63, + 0x43, 0x78, 0x79, 0x7A, 0x03, 0x14, 0x10, 0x41, 0x61, 0x28, 0x0C, 0x41, 0x62, + 0x1A, 0x41, 0x63, 0x43, 0x78, 0x79, 0x7A, 0x03, 0x02>> + ) == expected end test "fixed size array of mix types" do expected = [ - %{ "key" => 42 }, + %{"key" => 42}, "fooooobar", "x", <<0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08>> ] + data = << - 0x02, 0x2a, - 0x0b, 0x0a, 0x01, 0x43, 0x6b, 0x65, 0x79, 0x21, 0x2a, 0x00, # object - 0x49, 0x66, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x62, 0x61, 0x72, # string "fooooobar" - 0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, # string "x" - 0xc0, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 # binary data + 0x02, + 0x2A, + # object + 0x0B, + 0x0A, + 0x01, + 0x43, + 0x6B, + 0x65, + 0x79, + 0x28, + 0x2A, + 0x03, + # string "fooooobar" + 0x49, + 0x66, + 0x6F, + 0x6F, + 0x6F, + 0x6F, + 0x6F, + 0x62, + 0x61, + 0x72, + # string "x" + 0xBF, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + # binary data + 0xC0, + 0x08, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08 >> + assert decode!(data) == expected end test "object 1 byte offset" do - expected = %{"0" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "1" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "2" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "3" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "4" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}} - - assert decode!(<<0x0b, 0xe9, 0x05, 0x41, 0x30, 0x0b, 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, - 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, - 0x41, 0x31, 0x0b, 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, - 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x41, 0x32, 0x0b, - 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, - 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x41, 0x33, 0x0b, 0x2b, 0x05, 0x41, - 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, - 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x41, 0x34, 0x0b, 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, - 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, - 0x0a, 0x11, 0x18, 0x1f, 0x03, 0x30, 0x5d, 0x8a, 0xb7>>) == expected + expected = %{ + "0" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "1" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "2" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "3" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "4" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"} + } + + assert decode!( + <<0x0B, 0xE9, 0x05, 0x41, 0x30, 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x41, 0x31, 0x0B, 0x2B, + 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, + 0x18, 0x1F, 0x41, 0x32, 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x41, 0x33, 0x0B, 0x2B, 0x05, + 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, + 0x1F, 0x41, 0x34, 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x03, 0x30, 0x5D, 0x8A, 0xB7>> + ) == expected end test "object 2 bytes offset" do - expected = %{"0" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "1" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "2" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "3" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "4" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "5" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "6" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "7" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "8" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "9" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}} - - assert decode!(<<0x0c, 0x6f, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, - 0x30, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x31, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x32, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x33, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x34, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x35, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x36, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x37, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x38, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x39, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x09, - 0x00, 0x5e, 0x00, 0xb3, 0x00, 0x08, 0x01, 0x5d, 0x01, 0xb2, 0x01, 0x07, 0x02, 0x5c, 0x02, 0xb1, 0x02, - 0x06, 0x03>>) == expected + expected = %{ + "0" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "1" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "2" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "3" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "4" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "5" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "6" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "7" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "8" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "9" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + } + } + + assert decode!( + <<0x0C, 0x6F, 0x03, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x30, 0x0B, 0x53, + 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, + 0x34, 0x3B, 0x42, 0x41, 0x31, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x32, 0x0B, + 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, + 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x33, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x34, + 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, + 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x35, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, + 0x36, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, + 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x37, 0x0B, 0x53, 0x0A, 0x41, 0x30, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, + 0x41, 0x38, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, + 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x39, 0x0B, 0x53, 0x0A, 0x41, + 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, + 0x42, 0x09, 0x00, 0x5E, 0x00, 0xB3, 0x00, 0x08, 0x01, 0x5D, 0x01, 0xB2, 0x01, + 0x07, 0x02, 0x5C, 0x02, 0xB1, 0x02, 0x06, 0x03>> + ) == expected end end end diff --git a/test/encoder_test.exs b/test/encoder_test.exs index 06f36c9..8e2d4ef 100644 --- a/test/encoder_test.exs +++ b/test/encoder_test.exs @@ -1,6 +1,5 @@ defmodule VelocyPack.EncoderTest do - use ExUnit.Case - doctest VelocyPack + use ExUnit.Case, async: true import VelocyPack @@ -15,17 +14,17 @@ defmodule VelocyPack.EncoderTest do test "boolean" do assert encode!(false) == <<0x19>> - assert encode!(true) == <<0x1a>> + assert encode!(true) == <<0x1A>> end test "double" do - assert encode!(133.7) == <<0x1b, 0x66, 0x66, 0x66, 0x66, 0x66, 0xb6, 0x60, 0x40>>; - assert encode!(-133.7) == <<0x1b, 0x66, 0x66, 0x66, 0x66, 0x66, 0xb6, 0x60, 0xc0>>; + assert encode!(133.7) == <<0x1B, 0x66, 0x66, 0x66, 0x66, 0x66, 0xB6, 0x60, 0x40>> + assert encode!(-133.7) == <<0x1B, 0x66, 0x66, 0x66, 0x66, 0x66, 0xB6, 0x60, 0xC0>> end test "min/max key" do - assert encode!(:min_key) == <<0x1e>> - assert encode!(:max_key) == <<0x1f>> + assert encode!(:min_key) == <<0x1E>> + assert encode!(:max_key) == <<0x1F>> end test "small int" do @@ -39,85 +38,101 @@ defmodule VelocyPack.EncoderTest do assert encode!(7) == <<0x37>> assert encode!(8) == <<0x38>> assert encode!(9) == <<0x39>> - assert encode!(-6) == <<0x3a>> - assert encode!(-5) == <<0x3b>> - assert encode!(-4) == <<0x3c>> - assert encode!(-3) == <<0x3d>> - assert encode!(-2) == <<0x3e>> - assert encode!(-1) == <<0x3f>> + assert encode!(-6) == <<0x3A>> + assert encode!(-5) == <<0x3B>> + assert encode!(-4) == <<0x3C>> + assert encode!(-3) == <<0x3D>> + assert encode!(-2) == <<0x3E>> + assert encode!(-1) == <<0x3F>> end test "int" do - assert encode!(-7) == <<0x20, (-7)::little-signed>> + assert encode!(-7) == <<0x20, -7::little-signed>> assert encode!(-128) == <<0x20, 0x80>> assert encode!(-32768) == <<0x21, 0x00, 0x80>> - assert encode!(-8388608) == <<0x22, 0x00, 0x00, 0x80>> - assert encode!(-2147483648) == <<0x23, 0x00, 0x00, 0x00, 0x80>> - assert encode!(-549755813888) == <<0x24, 0x00, 0x00, 0x00, 0x00, 0x80>> - assert encode!(-140737488355328) == <<0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80>> - assert encode!(-36028797018963968) == <<0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80>> - assert encode!(-9223372036854775808) == <<0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80>> - - assert encode!(255) == <<0x28, 0xff>> - assert encode!(65535) == <<0x29, 0xff, 0xff>> - assert encode!(16777215) == <<0x2a, 0xff, 0xff, 0xff>> - assert encode!(4294967295) == <<0x2b, 0xff, 0xff, 0xff, 0xff>> - assert encode!(1099511627775) == <<0x2c, 0xff, 0xff, 0xff, 0xff, 0xff>> - assert encode!(281474976710655) == <<0x2d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>> - assert encode!(72057594037927935) == <<0x2e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>> - assert encode!(18446744073709551615) == <<0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff>> + assert encode!(-8_388_608) == <<0x22, 0x00, 0x00, 0x80>> + assert encode!(-2_147_483_648) == <<0x23, 0x00, 0x00, 0x00, 0x80>> + assert encode!(-549_755_813_888) == <<0x24, 0x00, 0x00, 0x00, 0x00, 0x80>> + assert encode!(-140_737_488_355_328) == <<0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80>> + + assert encode!(-36_028_797_018_963_968) == + <<0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80>> + + assert encode!(-9_223_372_036_854_775_808) == + <<0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80>> + + assert encode!(255) == <<0x28, 0xFF>> + assert encode!(65535) == <<0x29, 0xFF, 0xFF>> + assert encode!(16_777_215) == <<0x2A, 0xFF, 0xFF, 0xFF>> + assert encode!(4_294_967_295) == <<0x2B, 0xFF, 0xFF, 0xFF, 0xFF>> + assert encode!(1_099_511_627_775) == <<0x2C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>> + assert encode!(281_474_976_710_655) == <<0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>> + assert encode!(72_057_594_037_927_935) == <<0x2E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>> + + assert encode!(18_446_744_073_709_551_615) == + <<0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF>> end test "short string" do - assert encode!("Hallo Welt!") == <<0x4b, 72, 97, 108, 108, 111, 32, 87, 101, 108, 116, 33>> - assert encode!("Hello World!") == <<0x4c, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33>> + assert encode!("Hallo Welt!") == <<0x4B, 72, 97, 108, 108, 111, 32, 87, 101, 108, 116, 33>> + + assert encode!("Hello World!") == + <<0x4C, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33>> end test "string" do - data = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. " - <> "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " - <> "Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. " - <> "Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, " - <> "venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. " - <> "Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." - expected = << - 0xbf, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6f, 0x72, 0x65, 0x6d, - 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, - 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, - 0x75, 0x65, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x65, - 0x6c, 0x69, 0x74, 0x2e, 0x20, 0x41, 0x65, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x64, 0x6f, 0x20, 0x6c, 0x69, 0x67, 0x75, 0x6c, 0x61, 0x20, 0x65, 0x67, 0x65, 0x74, 0x20, - 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x20, 0x41, 0x65, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6d, 0x61, - 0x73, 0x73, 0x61, 0x2e, 0x20, 0x43, 0x75, 0x6d, 0x20, 0x73, 0x6f, 0x63, 0x69, 0x69, 0x73, 0x20, - 0x6e, 0x61, 0x74, 0x6f, 0x71, 0x75, 0x65, 0x20, 0x70, 0x65, 0x6e, 0x61, 0x74, 0x69, 0x62, 0x75, - 0x73, 0x20, 0x65, 0x74, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x20, - 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x6f, 0x6e, 0x74, 0x65, - 0x73, 0x2c, 0x20, 0x6e, 0x61, 0x73, 0x63, 0x65, 0x74, 0x75, 0x72, 0x20, 0x72, 0x69, 0x64, 0x69, - 0x63, 0x75, 0x6c, 0x75, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x2e, 0x20, 0x44, 0x6f, 0x6e, 0x65, 0x63, - 0x20, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x66, 0x65, 0x6c, 0x69, 0x73, 0x2c, 0x20, 0x75, 0x6c, 0x74, - 0x72, 0x69, 0x63, 0x69, 0x65, 0x73, 0x20, 0x6e, 0x65, 0x63, 0x2c, 0x20, 0x70, 0x65, 0x6c, 0x6c, - 0x65, 0x6e, 0x74, 0x65, 0x73, 0x71, 0x75, 0x65, 0x20, 0x65, 0x75, 0x2c, 0x20, 0x70, 0x72, 0x65, - 0x74, 0x69, 0x75, 0x6d, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2c, 0x20, 0x73, 0x65, 0x6d, 0x2e, 0x20, - 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61, 0x74, 0x20, - 0x6d, 0x61, 0x73, 0x73, 0x61, 0x20, 0x71, 0x75, 0x69, 0x73, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x2e, - 0x20, 0x44, 0x6f, 0x6e, 0x65, 0x63, 0x20, 0x70, 0x65, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x73, 0x74, - 0x6f, 0x2c, 0x20, 0x66, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x6c, 0x6c, 0x61, 0x20, 0x76, 0x65, 0x6c, - 0x2c, 0x20, 0x61, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x74, 0x20, 0x6e, 0x65, 0x63, 0x2c, 0x20, 0x76, - 0x75, 0x6c, 0x70, 0x75, 0x74, 0x61, 0x74, 0x65, 0x20, 0x65, 0x67, 0x65, 0x74, 0x2c, 0x20, 0x61, - 0x72, 0x63, 0x75, 0x2e, 0x20, 0x49, 0x6e, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20, 0x6a, 0x75, 0x73, - 0x74, 0x6f, 0x2c, 0x20, 0x72, 0x68, 0x6f, 0x6e, 0x63, 0x75, 0x73, 0x20, 0x75, 0x74, 0x2c, 0x20, - 0x69, 0x6d, 0x70, 0x65, 0x72, 0x64, 0x69, 0x65, 0x74, 0x20, 0x61, 0x2c, 0x20, 0x76, 0x65, 0x6e, - 0x65, 0x6e, 0x61, 0x74, 0x69, 0x73, 0x20, 0x76, 0x69, 0x74, 0x61, 0x65, 0x2c, 0x20, 0x6a, 0x75, - 0x73, 0x74, 0x6f, 0x2e, 0x20, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x6d, 0x20, 0x64, 0x69, 0x63, 0x74, - 0x75, 0x6d, 0x20, 0x66, 0x65, 0x6c, 0x69, 0x73, 0x20, 0x65, 0x75, 0x20, 0x70, 0x65, 0x64, 0x65, - 0x20, 0x6d, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x74, 0x69, 0x75, 0x6d, 0x2e, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x75, - 0x6e, 0x74, 0x2e, 0x20, 0x43, 0x72, 0x61, 0x73, 0x20, 0x64, 0x61, 0x70, 0x69, 0x62, 0x75, 0x73, - 0x2e, 0x20, 0x56, 0x69, 0x76, 0x61, 0x6d, 0x75, 0x73, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x75, 0x6d, 0x20, 0x73, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x20, 0x6e, 0x69, 0x73, 0x69, 0x2e, - 0x20, 0x41, 0x65, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x76, 0x75, 0x6c, 0x70, 0x75, 0x74, 0x61, 0x74, - 0x65, 0x20, 0x65, 0x6c, 0x65, 0x69, 0x66, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x65, 0x6c, 0x6c, 0x75, - 0x73, 0x2e>> + data = + "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. " <> + "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " <> + "Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. " <> + "Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, " <> + "venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. " <> + "Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." + + expected = + <<0xBF, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x6F, 0x72, 0x65, 0x6D, + 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, + 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, + 0x63, 0x74, 0x65, 0x74, 0x75, 0x65, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, + 0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20, 0x41, 0x65, 0x6E, + 0x65, 0x61, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x6C, 0x69, + 0x67, 0x75, 0x6C, 0x61, 0x20, 0x65, 0x67, 0x65, 0x74, 0x20, 0x64, 0x6F, 0x6C, 0x6F, + 0x72, 0x2E, 0x20, 0x41, 0x65, 0x6E, 0x65, 0x61, 0x6E, 0x20, 0x6D, 0x61, 0x73, 0x73, + 0x61, 0x2E, 0x20, 0x43, 0x75, 0x6D, 0x20, 0x73, 0x6F, 0x63, 0x69, 0x69, 0x73, 0x20, + 0x6E, 0x61, 0x74, 0x6F, 0x71, 0x75, 0x65, 0x20, 0x70, 0x65, 0x6E, 0x61, 0x74, 0x69, + 0x62, 0x75, 0x73, 0x20, 0x65, 0x74, 0x20, 0x6D, 0x61, 0x67, 0x6E, 0x69, 0x73, 0x20, + 0x64, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x69, 0x65, 0x6E, 0x74, + 0x20, 0x6D, 0x6F, 0x6E, 0x74, 0x65, 0x73, 0x2C, 0x20, 0x6E, 0x61, 0x73, 0x63, 0x65, + 0x74, 0x75, 0x72, 0x20, 0x72, 0x69, 0x64, 0x69, 0x63, 0x75, 0x6C, 0x75, 0x73, 0x20, + 0x6D, 0x75, 0x73, 0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20, 0x71, 0x75, 0x61, + 0x6D, 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x2C, 0x20, 0x75, 0x6C, 0x74, 0x72, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x20, 0x6E, 0x65, 0x63, 0x2C, 0x20, 0x70, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x74, 0x65, 0x73, 0x71, 0x75, 0x65, 0x20, 0x65, 0x75, 0x2C, 0x20, 0x70, + 0x72, 0x65, 0x74, 0x69, 0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20, 0x73, + 0x65, 0x6D, 0x2E, 0x20, 0x4E, 0x75, 0x6C, 0x6C, 0x61, 0x20, 0x63, 0x6F, 0x6E, 0x73, + 0x65, 0x71, 0x75, 0x61, 0x74, 0x20, 0x6D, 0x61, 0x73, 0x73, 0x61, 0x20, 0x71, 0x75, + 0x69, 0x73, 0x20, 0x65, 0x6E, 0x69, 0x6D, 0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, + 0x20, 0x70, 0x65, 0x64, 0x65, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x2C, 0x20, 0x66, + 0x72, 0x69, 0x6E, 0x67, 0x69, 0x6C, 0x6C, 0x61, 0x20, 0x76, 0x65, 0x6C, 0x2C, 0x20, + 0x61, 0x6C, 0x69, 0x71, 0x75, 0x65, 0x74, 0x20, 0x6E, 0x65, 0x63, 0x2C, 0x20, 0x76, + 0x75, 0x6C, 0x70, 0x75, 0x74, 0x61, 0x74, 0x65, 0x20, 0x65, 0x67, 0x65, 0x74, 0x2C, + 0x20, 0x61, 0x72, 0x63, 0x75, 0x2E, 0x20, 0x49, 0x6E, 0x20, 0x65, 0x6E, 0x69, 0x6D, + 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x2C, 0x20, 0x72, 0x68, 0x6F, 0x6E, 0x63, 0x75, + 0x73, 0x20, 0x75, 0x74, 0x2C, 0x20, 0x69, 0x6D, 0x70, 0x65, 0x72, 0x64, 0x69, 0x65, + 0x74, 0x20, 0x61, 0x2C, 0x20, 0x76, 0x65, 0x6E, 0x65, 0x6E, 0x61, 0x74, 0x69, 0x73, + 0x20, 0x76, 0x69, 0x74, 0x61, 0x65, 0x2C, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x2E, + 0x20, 0x4E, 0x75, 0x6C, 0x6C, 0x61, 0x6D, 0x20, 0x64, 0x69, 0x63, 0x74, 0x75, 0x6D, + 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x20, 0x65, 0x75, 0x20, 0x70, 0x65, 0x64, 0x65, + 0x20, 0x6D, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x74, 0x69, 0x75, + 0x6D, 0x2E, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0x20, 0x74, 0x69, 0x6E, + 0x63, 0x69, 0x64, 0x75, 0x6E, 0x74, 0x2E, 0x20, 0x43, 0x72, 0x61, 0x73, 0x20, 0x64, + 0x61, 0x70, 0x69, 0x62, 0x75, 0x73, 0x2E, 0x20, 0x56, 0x69, 0x76, 0x61, 0x6D, 0x75, + 0x73, 0x20, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x73, 0x65, + 0x6D, 0x70, 0x65, 0x72, 0x20, 0x6E, 0x69, 0x73, 0x69, 0x2E, 0x20, 0x41, 0x65, 0x6E, + 0x65, 0x61, 0x6E, 0x20, 0x76, 0x75, 0x6C, 0x70, 0x75, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x65, 0x6C, 0x65, 0x69, 0x66, 0x65, 0x6E, 0x64, 0x20, 0x74, 0x65, 0x6C, 0x6C, 0x75, + 0x73, 0x2E>> + assert encode!(data) == expected end @@ -135,13 +150,15 @@ defmodule VelocyPack.EncoderTest do <<0x03, _::binary>> = encoded = encode!(v) assert decode!(encoded) == v - v = for i <- 65537..131072, do: i + v = for i <- 65537..131_072, do: i <<0x04, _::binary>> = encoded = encode!(v) assert decode!(encoded) == v end test "lists with different sized elements as arrays with index table" do - assert encode!([256, 1, 2]) == <<0x06, 0x0b, 0x3, 0x29, 256::little-unsigned-size(16), "1", "2", 0x03, 0x06, 0x07>> + assert encode!([256, 1, 2]) == + <<0x06, 0x0B, 0x3, 0x29, 256::little-unsigned-size(16), "1", "2", 0x03, 0x06, + 0x07>> v = for i <- 1..64, do: i <<0x06, _::binary>> = encoded = encode!(v) @@ -161,132 +178,262 @@ defmodule VelocyPack.EncoderTest do # This test covers the corner case were, due to the number of bytes required for the size # information itself, an additional byte is needed to encode the final total size. - s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. " - <> "Aenean massa. Cum sociis ..." + s = + "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. " <> + "Aenean massa. Cum sociis ..." + v = [s, 1, 2, 42] <<0x13, _::binary>> = encoded = encode!(v, compact_arrays: true) assert decode!(encoded) == v end test "nested list" do - expected = <<0x02, 0x0c, 0x02, 0x05, 0x31, 0x32, 0x33, 0x02, 0x05, 0x31, 0x32, 0x33>> + expected = <<0x02, 0x0C, 0x02, 0x05, 0x31, 0x32, 0x33, 0x02, 0x05, 0x31, 0x32, 0x33>> data = [[1, 2, 3], [1, 2, 3]] assert encode!(data) == expected end test "empty object" do - assert encode!(%{}) == <<0x0a>> + assert encode!(%{}) == <<0x0A>> end test "object with string and atom keys" do - assert encode!(%{ "a" => "b" }) == <<0x0b, 0x07, 0x01, 0x41, 0x61, 0x41, 0x62>> - assert encode!(%{ a: "b", b: "a" }) == <<0x0b, 0x0d, 0x02, 0x41, 0x61, 0x41, 0x62, 0x41, 0x62, 0x41, 0x61, 0x03, 0x07>> + assert encode!(%{"a" => "b"}) == <<0x0B, 0x08, 0x01, 0x41, 0x61, 0x41, 0x62, 0x03>> + + assert encode!(%{a: "b", b: "a"}) == + <<0x0B, 0x0D, 0x02, 0x41, 0x61, 0x41, 0x62, 0x41, 0x62, 0x41, 0x61, 0x03, 0x07>> end test "object 1 byte offset" do - data = %{"0" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "1" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "2" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "3" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}, - "4" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test"}} - expected = <<0x0b, 0xe9, 0x05, 0x41, 0x30, 0x0b, 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, - 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, - 0x41, 0x31, 0x0b, 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, - 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x41, 0x32, 0x0b, - 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, - 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x41, 0x33, 0x0b, 0x2b, 0x05, 0x41, - 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, - 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x41, 0x34, 0x0b, 0x2b, 0x05, 0x41, 0x30, 0x44, 0x74, - 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, - 0x0a, 0x11, 0x18, 0x1f, 0x03, 0x30, 0x5d, 0x8a, 0xb7>> + data = %{ + "0" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "1" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "2" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "3" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"}, + "4" => %{"0" => "test", "1" => "test", "2" => "test", "3" => "test", "4" => "test"} + } + + expected = + <<0x0B, 0xE9, 0x05, 0x41, 0x30, 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x41, 0x31, 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x41, 0x32, 0x0B, 0x2B, 0x05, + 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x41, 0x33, + 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, + 0x1F, 0x41, 0x34, 0x0B, 0x2B, 0x05, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, + 0x0A, 0x11, 0x18, 0x1F, 0x03, 0x30, 0x5D, 0x8A, 0xB7>> + assert encode!(data) == expected end test "object 2 bytes offset" do - data = %{"0" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "1" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "2" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "3" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "4" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "5" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "6" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "7" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "8" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}, - "9" => %{"0" => "test","1" => "test","2" => "test","3" => "test","4" => "test","5" => - "test","6" => "test","7" => "test","8" => "test","9" => "test"}} - expected = <<0x0c, 0x6b, 0x03, 0x0a, 0x00, 0x41, - 0x30, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x31, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x32, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x33, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x34, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x35, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x36, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x37, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x38, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x41, - 0x39, 0x0b, 0x53, 0x0a, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, - 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, - 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, - 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, - 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0a, 0x11, 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x05, - 0x00, 0x5a, 0x00, 0xaf, 0x00, 0x04, 0x01, 0x59, 0x01, 0xae, 0x01, 0x03, 0x02, 0x58, 0x02, 0xad, 0x02, - 0x02, 0x03>> + data = %{ + "0" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "1" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "2" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "3" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "4" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "5" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "6" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "7" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "8" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + }, + "9" => %{ + "0" => "test", + "1" => "test", + "2" => "test", + "3" => "test", + "4" => "test", + "5" => "test", + "6" => "test", + "7" => "test", + "8" => "test", + "9" => "test" + } + } + + expected = + <<0x0C, 0x6B, 0x03, 0x0A, 0x00, 0x41, 0x30, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, + 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x31, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, + 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x32, 0x0B, 0x53, 0x0A, 0x41, 0x30, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, + 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x33, 0x0B, 0x53, 0x0A, 0x41, + 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, + 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, + 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x34, 0x0B, 0x53, 0x0A, + 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, 0x74, + 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x35, 0x0B, 0x53, + 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, 0x73, + 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x36, 0x0B, + 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, 0x65, + 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, 0x37, + 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, 0x74, + 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, 0x41, + 0x38, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, 0x44, + 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x42, + 0x41, 0x39, 0x0B, 0x53, 0x0A, 0x41, 0x30, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x31, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x32, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x33, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x34, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x35, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x36, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x37, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x38, 0x44, 0x74, 0x65, 0x73, 0x74, 0x41, 0x39, + 0x44, 0x74, 0x65, 0x73, 0x74, 0x03, 0x0A, 0x11, 0x18, 0x1F, 0x26, 0x2D, 0x34, 0x3B, + 0x42, 0x05, 0x00, 0x5A, 0x00, 0xAF, 0x00, 0x04, 0x01, 0x59, 0x01, 0xAE, 0x01, 0x03, + 0x02, 0x58, 0x02, 0xAD, 0x02, 0x02, 0x03>> + assert encode!(data) == expected end test "compact object" do data = %{"a" => 12, "b" => true, "c" => "xyz"} - expected = <<0x14, 0x10, 0x41, 0x61, 0x28, 0x0c, 0x41, 0x62, 0x1a, 0x41, 0x63, 0x43, 0x78, 0x79, 0x7a, 0x03>> + + expected = + <<0x14, 0x10, 0x41, 0x61, 0x28, 0x0C, 0x41, 0x62, 0x1A, 0x41, 0x63, 0x43, 0x78, 0x79, + 0x7A, 0x03>> + assert encode!(data, compact_objects: true) == expected end end diff --git a/test/velocy_pack_test.exs b/test/velocy_pack_test.exs new file mode 100644 index 0000000..35b0df7 --- /dev/null +++ b/test/velocy_pack_test.exs @@ -0,0 +1,4 @@ +defmodule VelocyPackTest do + use ExUnit.Case, async: true + doctest VelocyPack +end