# frozen_string_literal: true
require "minitest/autorun"
require "dhall"
class TestCoder < Minitest::Test
def test_dump_integer
assert_equal "\x82\x0F\x01".b, Dhall::Coder.dump(1)
end
def test_dump_integer_negative
assert_equal "\x82\x10 ".b, Dhall::Coder.dump(-1)
end
def test_dump_float
assert_equal "\xFA?\x80\x00\x00".b, Dhall::Coder.dump(1.0)
end
def test_dump_string
assert_equal "\x82\x12ehello".b, Dhall::Coder.dump("hello")
end
def test_dump_nil
assert_nil Dhall::Coder.dump(nil)
end
def test_dump_array
assert_equal(
"\x84\x04\xF6\x82\x0F\x01\x82\x0F\x02".b,
Dhall::Coder.dump([1, 2])
)
end
def test_dump_array_with_nil
assert_equal(
"\x84\x04\xF6\x83\x05\xF6\x82\x0F\x01\x83\x00dNonegNatural".b,
Dhall::Coder.dump([1, nil])
)
end
class EmptyObject
def ==(other)
other.is_a?(EmptyObject)
end
end
def test_dump_array_heterogenous
assert_equal(
"\x86\x04\xF6\x83\x00\x83\t\x82\v\xA4gNaturalgNaturaldNone" \
"\xF6vTestCoder::EmptyObject\x82\a\xA0dboop\xF6gNatural\x82" \
"\x0F\x01\x83\t\x82\v\xA4gNaturalgNaturaldNone" \
"\xF6vTestCoder::EmptyObject\x82\a\xA0dboop\xF6dNone" \
"\x83\t\x82\v\xA4gNaturalgNaturaldNone\xF6vTestCoder::EmptyObject" \
"\x82\a\xA0dboop\xF6dboop\x83\x00\x83\t\x82\v\xA4" \
"gNaturalgNaturaldNone\xF6vTestCoder::EmptyObject" \
"\x82\a\xA0dboop\xF6vTestCoder::EmptyObject\x82\b\xA0".b,
Dhall::Coder.dump([1, nil, :boop, EmptyObject.new])
)
end
def test_dump_hash
assert_equal(
"\x82\b\xA2aa\x82\x0F\x01ab\xFA?\x80\x00\x00".b,
Dhall::Coder.dump(a: 1, b: 1.0)
)
end
def test_dump_object
assert_raises ArgumentError do
Dhall::Coder.dump(Object.new)
end
end
def test_load_loaded
assert_equal 1, Dhall::Coder.load(1)
end
def test_load_integer
assert_equal 1, Dhall::Coder.load("\x82\x0F\x01".b)
end
def test_load_integer_negative
assert_equal(-1, Dhall::Coder.load("\x82\x10 ".b))
end
def test_load_float
assert_equal 1.0, Dhall::Coder.load("\xFA?\x80\x00\x00".b)
end
def test_load_string
assert_equal "hello", Dhall::Coder.load("\x82\x12ehello".b)
end
def test_load_nil
assert_nil Dhall::Coder.load(nil)
end
def test_load_array
assert_equal(
[1, 2],
Dhall::Coder.load("\x84\x04\xF6\x82\x0F\x01\x82\x0F\x02".b)
)
end
def test_load_array_with_nil
assert_equal(
[1, nil],
Dhall::Coder.load(
"\x84\x04\xF6\x83\x05\xF6\x82\x0F\x01\x83\x00dNonegNatural".b
)
)
end
def test_load_array_heterogenous
coder = Dhall::Coder.new(safe: Object) # unsafe coder
assert_equal(
[1, nil, :boop, EmptyObject.new],
coder.load(
"\x86\x04\xF6\x83\x00\x83\t\x82\v\xA4gNaturalgNaturaldNone" \
"\xF6vTestCoder::EmptyObject\x82\a\xA0dboop\xF6gNatural\x82" \
"\x0F\x01\x83\t\x82\v\xA4gNaturalgNaturaldNone" \
"\xF6vTestCoder::EmptyObject\x82\a\xA0dboop\xF6dNone" \
"\x83\t\x82\v\xA4gNaturalgNaturaldNone\xF6vTestCoder::EmptyObject" \
"\x82\a\xA0dboop\xF6dboop\x83\x00\x83\t\x82\v\xA4" \
"gNaturalgNaturaldNone\xF6vTestCoder::EmptyObject" \
"\x82\a\xA0dboop\xF6vTestCoder::EmptyObject\x82\b\xA0".b
)
)
end
def test_load_hash
assert_equal(
{ "a" => 1, "b" => 1.0 },
Dhall::Coder.load("\x82\b\xA2aa\x82\x0F\x01ab\xFA?\x80\x00\x00".b)
)
end
def test_load_hash_symbolize
assert_equal(
{ a: 1, b: 1.0 },
Dhall::Coder.load(
"\x82\b\xA2aa\x82\x0F\x01ab\xFA?\x80\x00\x00".b,
transform_keys: :to_sym
)
)
end
def test_load_object
assert_raises ArgumentError do
Dhall::Coder.load(
"\x83\x00\x83\t\x82\v\xA1fObject\x82\a\xA0fObject\x82\b\xA0".b
)
end
end
def test_decode_proc
coder = Dhall::Coder.new(safe: [Proc, NilClass, Integer])
assert_equal(
2,
coder.decode(Dhall.load("\\(x: Natural) -> x + 1").sync).call(1)
)
end
class Custom
attr_reader :a, :b
def initialize
@a = true
@b = "true"
end
def ==(other)
a == other.a && b == other.b
end
end
def test_bad_default
assert_raises ArgumentError do
Dhall::Coder.new(safe: Custom)
end
end
def test_dump_custom
assert_equal(
"\x83\x00\x83\t\x82\v\xA1qTestCoder::Custom\x82\a\xA2aadBoolabd" \
"TextqTestCoder::Custom\x82\b\xA2aa\xF5ab\x82\x12dtrue".b,
Dhall::Coder.new(default: Custom.new, safe: Custom).dump(Custom.new)
)
end
def test_load_custom
coder = Dhall::Coder.new(
default: Custom.new,
safe: Dhall::Coder::JSON_LIKE + [Custom]
)
assert_equal(
Custom.new,
coder.load(
"\x83\x00\x83\t\x82\v\xA1qTestCoder::Custom\x82\a\xA2aadBoolabd" \
"TextqTestCoder::Custom\x82\b\xA2aa\xF5ab\x82\x12dtrue".b
)
)
end
class CustomCoding
attr_reader :a, :b
def initialize
@a = true
@b = "true"
end
def ==(other)
a == other.a && b == other.b
end
def init_with(coder)
@a = coder["abool"]
@b = coder["astring"]
end
def encode_with(coder)
coder["abool"] = @a
coder["astring"] = @b
end
end
def test_dump_custom_coding
assert_equal(
"\x83\x00\x83\t\x82\v\xA1wTestCoder::CustomCoding\x82\a\xA2" \
"eabooldBoolgastringdTextwTestCoder::CustomCoding\x82\b\xA2" \
"eabool\xF5gastring\x82\x12dtrue".b,
Dhall::Coder.new(
default: CustomCoding.new,
safe: CustomCoding
).dump(CustomCoding.new)
)
end
def test_load_custom_coding
coder = Dhall::Coder.new(
default: CustomCoding.new,
safe: Dhall::Coder::JSON_LIKE + [CustomCoding]
)
assert_equal(
CustomCoding.new,
coder.load(
"\x83\x00\x83\t\x82\v\xA1wTestCoder::CustomCoding\x82\a\xA2" \
"eabooldBoolgastringdTextwTestCoder::CustomCoding\x82\b\xA2" \
"eabool\xF5gastring\x82\x12dtrue".b
)
)
end
class CustomDhall
using Dhall::AsDhall
attr_reader :str
def self.from_dhall(expr)
new(expr.to_s)
end
def initialize(str="test")
@str = str
end
def ==(other)
str == other.str
end
def as_dhall
Dhall::Union.from(
Dhall::UnionType.new(
alternatives: { self.class.name => Dhall::Text.as_dhall }
),
self.class.name,
@str.as_dhall
)
end
end
def test_dump_custom_dhall
assert_equal(
"\x83\x00\x83\t\x82\v\xA1vTestCoder::CustomDhalldText" \
"vTestCoder::CustomDhall\x82\x12dtest".b,
Dhall::Coder.new(
default: CustomDhall.new,
safe: CustomDhall
).dump(CustomDhall.new)
)
end
def test_load_custom_dhall
coder = Dhall::Coder.new(
default: CustomDhall.new,
safe: Dhall::Coder::JSON_LIKE + [CustomDhall]
)
assert_equal(
CustomDhall.new,
coder.load(
"\x83\x00\x83\t\x82\v\xA1vTestCoder::CustomDhalldText" \
"vTestCoder::CustomDhall\x82\x12dtest".b
)
)
end
class SomeTestClass
attr_reader :a, :b
def initialize(a: 1, b: "hai")
@a = a
@b = b
end
def ==(other)
a == other.a && b == other.b
end
end
def test_mixed_array_roundtrip
coder = Dhall::Coder.new(safe: Object) # unsafe coder
array = [
1, "hai", nil, :boop, true, false, { "a" => 1 }, [1],
SomeTestClass.new, SomeTestClass.new(a: "hai", b: 1)
]
assert_equal(array, coder.load(coder.dump(array)))
end
end