Skip to content

Commit

Permalink
test: Add TypedExecutionResult
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Nov 18, 2020
1 parent c30970f commit 3d14850
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
3 changes: 2 additions & 1 deletion test/unittests/execute_numeric_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ auto create_unary_operation_executor(Instr instr)

auto instance = instantiate(std::move(module));

return [instance = std::move(instance)](Value arg) { return execute(*instance, 0, {arg}); };
return
[instance = std::move(instance)](Value arg) { return typed_execute(*instance, 0, {arg}); };
}

auto create_binary_operation_executor(Instr instr)
Expand Down
52 changes: 51 additions & 1 deletion test/utils/asserts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@
#include <gmock/gmock.h>
#include <test/utils/floating_point_utils.hpp>
#include <iosfwd>
#include <type_traits>

namespace fizzy::test
{
struct TypedExecutionResult : ExecutionResult
{
ValType type;
TypedExecutionResult(ExecutionResult result, ValType t) noexcept
: ExecutionResult{result}, type{t}
{}
};

inline TypedExecutionResult typed_execute(
Instance& instance, FuncIdx func_idx, std::initializer_list<Value> args)
{
const auto& func_type = instance.module->get_function_type(func_idx);
assert(args.size() == func_type.inputs.size());
const auto result = execute(instance, func_idx, args.begin());
const auto result_type = func_type.outputs.empty() ? ValType{} : func_type.outputs[0];
return {result, result_type};
}
} // namespace fizzy::test

MATCHER(Traps, "") // NOLINT(readability-redundant-string-init)
{
Expand All @@ -21,13 +43,41 @@ MATCHER(Result, "empty result")
return !arg.trapped && !arg.has_value;
}

template <typename T, typename... Ts>
constexpr bool is_any_of = std::disjunction_v<std::is_same<T, Ts>...>;

MATCHER_P(Result, value, "") // NOLINT(readability-redundant-string-init)
{
using namespace fizzy;
static_assert(is_any_of<value_type, uint32_t, int32_t, uint64_t, int64_t, float, double>);

if (arg.trapped || !arg.has_value)
return false;

using result_type = std::remove_cv_t<std::remove_reference_t<arg_type>>;
if constexpr (std::is_same_v<result_type, test::TypedExecutionResult>)
{
// Type safe checks.
if constexpr (is_any_of<value_type, uint32_t, int32_t>)
{
return arg.type == ValType::i32 && arg.value.i64 == static_cast<uint32_t>(value);
}
else if constexpr (is_any_of<value_type, uint64_t, int64_t>)
{
return arg.type == ValType::i64 && arg.value.i64 == static_cast<uint64_t>(value);
}
else if constexpr (std::is_same_v<value_type, float>)
{
return arg.type == ValType::f32 && arg.value.f32 == test::FP{value};
}
else if constexpr (std::is_same_v<value_type, double>)
{
return arg.type == ValType::f64 && arg.value.f64 == test::FP{value};
}
}

if constexpr (std::is_floating_point_v<value_type>)
return arg.value.template as<value_type>() == fizzy::test::FP{value};
return arg.value.template as<value_type>() == test::FP{value};
else // always check 64 bit of result for all integers, including 32-bit results
return arg.value.i64 == static_cast<std::make_unsigned_t<value_type>>(value);
}
Expand Down

0 comments on commit 3d14850

Please sign in to comment.