# frozen_string_literal: true
require "base64"
require "webmock/minitest"
require "minitest/autorun"
require "dhall/resolve"
require "dhall/normalize"
require "dhall/binary"
class TestResolve < Minitest::Test
DIRPATH = Pathname.new(File.dirname(__FILE__))
TESTS = DIRPATH + "normalization/"
def setup
@resolver = Dhall::Resolvers::Default.new(
path_reader: lambda do |sources|
sources.map do |source|
Promise.resolve(Base64.decode64({
"var" => "AA",
"import" => "hRgY9gADY3Zhcg",
"a" => "hRgY9gADYWI",
"b" => "hRgY9gADYWE",
"self" => "hRgY9gADZHNlbGY",
"text" => "aGFp",
"moretext" => "hRgY9gEDZHRleHQ",
"2text" => "hAMGhRgY9gEDZHRleHSFGBj2AANobW9yZXRleHQ",
"using" => "iBgY9gAAhRgY9gADZ2hlYWRlcnNkZS50ZGF09g",
"headers" => "gwT2ggiiZmhlYWRlcoISYnRoZXZhbHVlghJidHY"
}.fetch(source.pathname.to_s)))
end
end
)
end
def test_nothing_to_resolve
expr = Dhall::Function.of_arguments(
Dhall::Variable["Natural"],
body: Dhall::Variable["_"]
)
assert_equal expr, expr.resolve(Dhall::Resolvers::None.new).sync
end
def test_import_as_text
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Text,
Dhall::Import::RelativePath.new("text")
)
assert_equal(
Dhall::Text.new(value: "hai"),
expr.resolve(@resolver).sync
)
end
def test_one_level_to_resolve
expr = Dhall::Function.of_arguments(
Dhall::Variable["Natural"],
body: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("var")
)
)
assert_equal(
expr.with(body: Dhall::Variable["_"]),
expr.resolve(@resolver).sync
)
end
def test_two_levels_to_resolve
expr = Dhall::Function.of_arguments(
Dhall::Variable["Natural"],
body: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("import")
)
)
assert_equal(
expr.with(body: Dhall::Variable["_"]),
expr.resolve(@resolver).sync
)
end
def test_self_loop
expr = Dhall::Function.of_arguments(
Dhall::Variable["Natural"],
body: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("self")
)
)
assert_raises Dhall::ImportLoopException do
expr.resolve(@resolver).sync
end
end
def test_two_level_loop
expr = Dhall::Function.of_arguments(
Dhall::Variable["Natural"],
body: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("a")
)
)
assert_raises Dhall::ImportLoopException do
expr.resolve(@resolver).sync
end
end
def test_two_references_no_loop
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("2text")
)
assert_equal(
Dhall::Operator::TextConcatenate.new(
lhs: Dhall::Text.new(value: "hai"),
rhs: Dhall::Text.new(value: "hai")
),
expr.resolve(@resolver).sync
)
end
def test_missing
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::MissingImport.new
)
assert_raises Dhall::ImportFailedException do
expr.resolve(@resolver).sync
end
end
def test_integrity_check_failure
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new("sha256", "badhash"),
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("var")
)
assert_raises Dhall::Import::IntegrityCheck::FailureException do
expr.resolve(@resolver).sync
end
end
def test_fallback_to_expr
expr = Dhall::Operator::ImportFallback.new(
lhs: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::MissingImport.new
),
rhs: Dhall::Variable["fallback"]
)
assert_equal Dhall::Variable["fallback"], expr.resolve(@resolver).sync
end
def test_fallback_to_import
expr = Dhall::Operator::ImportFallback.new(
lhs: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::MissingImport.new
),
rhs: Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("import")
)
)
assert_equal Dhall::Variable["_"], expr.resolve(@resolver).sync
end
def test_headers
stub_request(:get, "http://e.td/t")
.with(headers: { "Th" => "tv" })
.to_return(status: 200, body: "\x00")
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::RelativePath.new("using")
)
assert_equal Dhall::Variable["_"], expr.resolve(@resolver).sync
end
def test_ipfs
stub_request(:get, "http://localhost:8000/ipfs/TESTCID")
.to_return(status: 200, body: "\x00")
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::AbsolutePath.new("ipfs", "TESTCID")
)
assert_equal Dhall::Variable["_"], expr.resolve.sync
end
def test_ipfs_public_gateway
stub_request(:get, "http://localhost:8000/ipfs/TESTCID")
.to_return(status: 500)
stub_request(:get, "https://cloudflare-ipfs.com/ipfs/TESTCID")
.to_return(status: 200, body: "\x00")
expr = Dhall::Import.new(
Dhall::Import::IntegrityCheck.new,
Dhall::Import::Expression,
Dhall::Import::AbsolutePath.new("ipfs", "TESTCID")
)
assert_equal Dhall::Variable["_"], expr.resolve.sync
end
# Sanity check that all expressions can pass through the resolver
Pathname.glob(TESTS + "**/*A.dhallb").each do |path|
test = path.relative_path_from(TESTS).to_s.sub(/A\.dhallb$/, "")
next if test =~ /prelude\//
next if test =~ /remoteSystems/
define_method("test_#{test.gsub(/\//, "_")}") do
Dhall::Function.disable_alpha_normalization! if test =~ /^standard\//
assert_equal(
Dhall.from_binary((TESTS + "#{test}B.dhallb").binread),
Dhall.from_binary(path.binread).resolve.sync.normalize
)
Dhall::Function.enable_alpha_normalization! if test =~ /^standard\//
end
end
end