Harbor

branch main
showing the latest snapshot on main
diagnostics_test.odin 3.7 KB · Plain text
tests/render_ir/diagnostics_test.odin 0644 Raw
package render_ir_tests

import ir "../../render_ir"
import "core:testing"

@(test)
test_diagnostic_codes_are_stable :: proc(t: ^testing.T) {
	testing.expect_value(t, ir.format_code(.None), "RIR0000")
	testing.expect_value(t, ir.format_code(.Invalid_Handle), "RIR0001")
	testing.expect_value(t, ir.format_code(.Invalid_Resource), "RIR0002")
	testing.expect_value(t, ir.format_code(.Invalid_Pass), "RIR0003")
	testing.expect_value(t, ir.format_code(.Invalid_Pipeline), "RIR0004")
	testing.expect_value(t, ir.format_code(.Invalid_Command), "RIR0005")
	testing.expect_value(t, ir.format_code(.Invalid_Order), "RIR0006")
	testing.expect_value(t, ir.format_code(.Unsupported), "RIR0007")
	testing.expect_value(t, ir.format_code(.Invalid_Descriptor), "RIR0008")
	testing.expect_value(t, ir.format_code(.Resource_Feedback), "RIR0009")
	testing.expect_value(t, ir.format_code(.Access_Metadata_Missing), "RIR0010")
	testing.expect_value(t, ir.format_code(.Invalid_Mask), "RIR0011")
	testing.expect_value(t, ir.format_code(.Stencil_Unsupported), "RIR0012")
	testing.expect_value(t, ir.format_code(.Internal_Error), "RIR9999")
}

@(test)
test_has_errors :: proc(t: ^testing.T) {
	diagnostics := ir.init_diagnostics()
	defer ir.destroy_diagnostics(&diagnostics)

	ir.add_warning(&diagnostics, .Unsupported, "fallback path")
	testing.expect(t, !ir.has_errors(&diagnostics))
	testing.expect(t, !ir.has_errors_slice(diagnostics.items[:]))

	ir.add_error(&diagnostics, .Invalid_Handle, "bad handle")
	testing.expect(t, ir.has_errors(&diagnostics))
	testing.expect(t, ir.has_errors_slice(diagnostics.items[:]))
}

@(test)
test_format_diagnostic_without_span_omits_fake_location :: proc(t: ^testing.T) {
	msg := ir.format_diagnostic(
		{severity = .Error, code = .Invalid_Handle, message = "bad handle"},
	)
	defer delete(msg)

	testing.expect_value(t, msg, "error[RIR0001]: bad handle")
}

@(test)
test_format_diagnostic_with_command_handle :: proc(t: ^testing.T) {
	msg := ir.format_diagnostic(
		{
			severity = .Error,
			code = .Unsupported,
			message = "runtime lowering rejected command",
			command = ir.Command_Handle(7),
		},
	)
	defer delete(msg)

	testing.expect_value(t, msg, "error[RIR0007]: command #7: runtime lowering rejected command")
}

@(test)
test_format_diagnostic_with_file_and_code :: proc(t: ^testing.T) {
	msg := ir.format_diagnostic(
		{
			severity = .Warning,
			code = .Unsupported,
			message = "feature unavailable",
			span = {file = "frame.gpu", line_start = 4, col_start = 2},
		},
	)
	defer delete(msg)

	testing.expect_value(t, msg, "frame.gpu:4:2: warning[RIR0007]: feature unavailable")
}

@(test)
test_format_diagnostic_omits_none_code :: proc(t: ^testing.T) {
	msg := ir.format_diagnostic({severity = .Note, code = .None, message = "extra context"})
	defer delete(msg)

	testing.expect_value(t, msg, "note: extra context")
}

@(test)
test_format_diagnostic_with_source_underlines_span :: proc(t: ^testing.T) {
	msg := ir.format_diagnostic_with_source(
		{
			severity = .Error,
			code = .Invalid_Order,
			message = "draw before pass",
			span = {file = "frame.gpu", line_start = 2, col_start = 3, line_end = 2, col_end = 5},
		},
		"one\nabcdef\nthree",
	)
	defer delete(msg)

	expected := "frame.gpu:2:3: error[RIR0006]: draw before pass\n   2 | abcdef\n      |   ^^^"
	testing.expect_value(t, msg, expected)
}

@(test)
test_reset_and_destroy_diagnostics :: proc(t: ^testing.T) {
	diagnostics := ir.init_diagnostics()

	ir.add_error(&diagnostics, .Invalid_Command, "bad command")
	testing.expect(t, ir.has_errors(&diagnostics))

	ir.reset_diagnostics(&diagnostics)
	testing.expect_value(t, len(diagnostics.items), 0)
	testing.expect(t, !ir.has_errors(&diagnostics))

	ir.add_note(&diagnostics, .None, "done")
	ir.destroy_diagnostics(&diagnostics)
	testing.expect_value(t, len(diagnostics.items), 0)
}