setting up some tests...
This commit is contained in:
1 parent
1a60fd54fc
commit
4140e7e237
4 files changed
+202
No files matched your search
@@ -29,6 +29,7 @@ args:
|
||||
parser_bounds
|
||||
lexer_failures
|
||||
parse_body_messages
|
||||
dogfood_parse
|
||||
clang
|
||||
msvc : By default this project builds with clang, specifying msvc will build with MSVC.
|
||||
debug
|
||||
|
||||
@@ -79,6 +79,7 @@ Push-Location $path_root
|
||||
[bool] $parser_bounds = $false
|
||||
[bool] $lexer_failures = $false
|
||||
[bool] $parse_body_messages = $false
|
||||
[bool] $dogfood_parse = $false
|
||||
|
||||
[array] $vendors = @( "clang", "msvc" )
|
||||
|
||||
@@ -101,6 +102,7 @@ if ( $args ) { $args | ForEach-Object {
|
||||
"parser_bounds" { $parser_bounds = $true }
|
||||
"lexer_failures" { $lexer_failures = $true }
|
||||
"parse_body_messages" { $parse_body_messages = $true }
|
||||
"dogfood_parse" { $dogfood_parse = $true }
|
||||
}
|
||||
}}
|
||||
#endregion Arguments
|
||||
@@ -140,6 +142,7 @@ $cannot_build = $cannot_build -and $test -eq $false
|
||||
$cannot_build = $cannot_build -and $parser_bounds -eq $false
|
||||
$cannot_build = $cannot_build -and $lexer_failures -eq $false
|
||||
$cannot_build = $cannot_build -and $parse_body_messages -eq $false
|
||||
$cannot_build = $cannot_build -and $dogfood_parse -eq $false
|
||||
if ( $cannot_build ) {
|
||||
Stop-stage "No build target specified"
|
||||
}
|
||||
@@ -522,6 +525,30 @@ if ($parse_body_messages)
|
||||
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||
invoke-stageTool -stage "parse_body_messages" -compiled $result -executable $executable -path_work $path_probe
|
||||
}
|
||||
|
||||
if ($dogfood_parse)
|
||||
{
|
||||
$path_probe = join-path $path_test dogfood_parse
|
||||
$path_build = join-path $path_probe build
|
||||
if ( -not(Test-Path($path_build) )) {
|
||||
new-item -ItemType Directory -Path $path_build | Out-Null
|
||||
}
|
||||
|
||||
$includes = @( $path_base )
|
||||
$unit = join-path $path_probe "test.cpp"
|
||||
$executable = join-path $path_build "dogfood_parse.exe"
|
||||
|
||||
$compiler_args = @()
|
||||
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
||||
$compiler_args += $flag_cpp17
|
||||
|
||||
$linker_args = @(
|
||||
$flag_link_win_subsystem_console
|
||||
)
|
||||
|
||||
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||
invoke-stageTool -stage "dogfood_parse" -compiled $result -executable $executable -path_work $path_probe
|
||||
}
|
||||
#endregion Building
|
||||
|
||||
pop-location # $path_root
|
||||
|
||||
@@ -22,6 +22,7 @@ $path_test_gen = Join-Path $path_test gen
|
||||
$path_parser_bounds_build = Join-Path $path_test "parser_bounds\build"
|
||||
$path_lexer_failures_build = Join-Path $path_test "lexer_failures\build"
|
||||
$path_parse_body_messages_build = Join-Path $path_test "parse_body_messages\build"
|
||||
$path_dogfood_parse_build = Join-Path $path_test "dogfood_parse\build"
|
||||
$path_x64 = Join-Path $path_root x64
|
||||
$path_release = Join-Path $path_root release
|
||||
|
||||
@@ -70,6 +71,9 @@ if ( Test-Path $path_lexer_failures_build ) {
|
||||
if ( Test-Path $path_parse_body_messages_build ) {
|
||||
Remove-Item $path_parse_body_messages_build -Recurse -Verbose
|
||||
}
|
||||
if ( Test-Path $path_dogfood_parse_build ) {
|
||||
Remove-Item $path_dogfood_parse_build -Recurse -Verbose
|
||||
}
|
||||
if ( Test-Path $path_x64) {
|
||||
Remove-Item $path_x64 -Recurse -Verbose
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
#define GEN_TIME
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#include "gen.cpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
global int g_failures = 0;
|
||||
|
||||
internal void expect(int condition, Str label) {
|
||||
if (condition == false) { log_fmt("FAIL %S\n", label); ++g_failures; }
|
||||
}
|
||||
|
||||
internal Str body_text(CodeBody body) {
|
||||
return strbuilder_to_str(code_to_strbuilder(cast(Code, body)));
|
||||
}
|
||||
|
||||
internal b32 body_has_variable(CodeBody body, Str name) { for (Code member : body) {
|
||||
if (member->Type == CT_Variable && member->Name.is_equal(name)) return true;
|
||||
if ((member->Type == CT_Struct || member->Type == CT_Union) && member->Body.ast != nullptr) {
|
||||
if (body_has_variable(cast(CodeBody, member->Body), name))
|
||||
return true;
|
||||
}
|
||||
} return false; }
|
||||
|
||||
internal Str bad_at(Str good) {
|
||||
StrBuilder built = strbuilder_make_reserve(_ctx->Allocator_Temp, good.Len + 2);
|
||||
strbuilder_append_str(& built, good);
|
||||
strbuilder_append_str(& built, txt("\n@"));
|
||||
return strbuilder_to_str(built);
|
||||
}
|
||||
|
||||
internal void expect_context_good(Context* ctx, Str label) {
|
||||
Str def = txt("struct Context\n{\n\tContext* parent;\n};\n\nContext* make_context();\n");
|
||||
CodeBody body = parse_global_body(def);
|
||||
Code found = InvalidCode;
|
||||
for (Code code : body) if (code->Type == CT_Struct && code->Name.is_equal(txt("Context")))
|
||||
found = code;
|
||||
expect(found.ast != nullptr, label); if (found.ast != nullptr) {
|
||||
Code member = InvalidCode;
|
||||
for (Code code : cast(CodeBody, found->Body)) {
|
||||
if (code->Type == CT_Variable && code->Name.is_equal(txt("parent")))
|
||||
member = code;
|
||||
}
|
||||
expect(member.ast != nullptr, label);
|
||||
}
|
||||
expect(ctx->parse_info.messages == nullptr, label);
|
||||
expect(ctx->parse_info.lexed.messages == nullptr, label);
|
||||
}
|
||||
|
||||
internal void expect_context_bad(Str label) {
|
||||
Context ctx = {}; init(& ctx);
|
||||
Str good = txt("struct Context\n{\n\tContext* parent;\n};\n\nContext* make_context();\n");
|
||||
CodeBody body = parse_global_body(bad_at(good));
|
||||
Str text = body_text(body);
|
||||
expect(str_contains(text, txt("Context")), label);
|
||||
expect(str_contains(text, txt("parent")), label);
|
||||
expect(ctx.parse_info.lexed.messages != nullptr, label);
|
||||
if (ctx.parse_info.lexed.messages != nullptr) expect(str_contains(ctx.parse_info.lexed.messages->content, txt("Failed to lex token")), label);
|
||||
expect_context_good(&ctx, txt("context-reuse"));
|
||||
deinit(& ctx);
|
||||
}
|
||||
|
||||
internal Str vec_def() {
|
||||
Str type = txt("Vec2f");
|
||||
Str unit_type = txt("f32");
|
||||
return token_fmt("type", type, "unit_type", unit_type, stringize(
|
||||
struct <type>
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
<unit_type> x;
|
||||
<unit_type> y;
|
||||
};
|
||||
<unit_type> Basis[2];
|
||||
};
|
||||
};
|
||||
));
|
||||
}
|
||||
|
||||
internal void expect_vec_good(Context* ctx, Str label) {
|
||||
Str def = vec_def();
|
||||
expect(str_contains(def, txt("struct Vec2f")), txt("vec-def-struct"));
|
||||
expect(str_contains(def, txt("union")), txt("vec-def-union"));
|
||||
expect(str_contains(def, txt("f32 x;")), txt("vec-def-x"));
|
||||
expect(str_contains(def, txt("f32 y;")), txt("vec-def-y"));
|
||||
expect(str_contains(def, txt("f32 Basis[2]")), txt("vec-def-Basis"));
|
||||
CodeBody body = parse_global_body(def);
|
||||
expect(body_has_variable(body, txt("x")), txt("vec-ast-x"));
|
||||
expect(body_has_variable(body, txt("y")), txt("vec-ast-y"));
|
||||
Str text = body_text(body);
|
||||
expect(str_contains(text, txt("Vec2f")), txt("vec-name"));
|
||||
expect(str_contains(text, txt("x")), txt("vec-x"));
|
||||
expect(str_contains(text, txt("y")), txt("vec-y"));
|
||||
expect(ctx->parse_info.messages == nullptr, txt("vec-parser-messages"));
|
||||
expect(ctx->parse_info.lexed.messages == nullptr, txt("vec-lexer-messages"));
|
||||
}
|
||||
|
||||
internal void expect_vec_bad(Str label) {
|
||||
Context ctx = {}; init(& ctx);
|
||||
CodeBody body = parse_global_body(bad_at(vec_def()));
|
||||
Str text = body_text(body);
|
||||
expect(str_contains(text, txt("Vec2f")), label);
|
||||
expect(ctx.parse_info.lexed.messages != nullptr, label);
|
||||
if (ctx.parse_info.lexed.messages != nullptr) expect(str_contains(ctx.parse_info.lexed.messages->content, txt("Failed to lex token")), label);
|
||||
expect_vec_good(& ctx, txt("vec-reuse"));
|
||||
deinit(& ctx);
|
||||
}
|
||||
|
||||
internal Str unreal_def() { return txt("UCLASS()\nclass UGasaFixture\n{\n\tUPROPERTY()\n\tint Health;\n};\n"); }
|
||||
|
||||
internal void expect_unreal_good(Context* ctx, Str label) {
|
||||
CodeBody body = parse_global_body(unreal_def());
|
||||
Code found = InvalidCode;
|
||||
for (Code code : body) if (code->Type == CT_Class && code->Name.is_equal(txt("UGasaFixture")))
|
||||
found = code;
|
||||
expect(found.ast != nullptr, label); if (found.ast != nullptr) {
|
||||
b32 saw_prop = false;
|
||||
b32 saw_health = false;
|
||||
for (Code member : cast(CodeBody, found->Body)) {
|
||||
if ( member->Type == CT_Untyped && member->Name.starts_with(txt("UPROPERTY"))) saw_prop = true;
|
||||
if (saw_prop && member->Type == CT_Variable && member->Name.is_equal(txt("Health"))) saw_health = true;
|
||||
}
|
||||
expect(saw_prop, label);
|
||||
expect(saw_health, label);
|
||||
}
|
||||
expect(ctx->parse_info.messages == nullptr, label);
|
||||
expect(ctx->parse_info.lexed.messages == nullptr, label);
|
||||
}
|
||||
|
||||
internal void expect_unreal_bad(Str label) {
|
||||
Context ctx = {}; init(& ctx);
|
||||
register_macros(args(
|
||||
(Macro { txt("UCLASS"), MT_Statement, MF_Functional }),
|
||||
(Macro { txt("UPROPERTY"), MT_Statement, MF_Functional })
|
||||
));
|
||||
CodeBody body = parse_global_body(bad_at(unreal_def()));
|
||||
Str text = body_text(body);
|
||||
expect(str_contains(text, txt("UGasaFixture")), label);
|
||||
expect(ctx.parse_info.lexed.messages != nullptr, label);
|
||||
if (ctx.parse_info.lexed.messages != nullptr) expect(str_contains(ctx.parse_info.lexed.messages->content, txt("Failed to lex token")), label);
|
||||
expect_unreal_good(&ctx, txt("unreal-reuse"));
|
||||
deinit(& ctx);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Context ctx = {}; init(& ctx);
|
||||
expect_context_good(&ctx, txt("context"));
|
||||
deinit(& ctx);
|
||||
expect_context_bad(txt("context-at"));
|
||||
|
||||
init(& ctx);
|
||||
expect_vec_good(& ctx, txt("vec"));
|
||||
deinit(& ctx);
|
||||
expect_vec_bad(txt("vec-at"));
|
||||
|
||||
init(& ctx);
|
||||
register_macros(args(
|
||||
(Macro { txt("UCLASS"), MT_Statement, MF_Functional }),
|
||||
(Macro { txt("UPROPERTY"), MT_Statement, MF_Functional })
|
||||
));
|
||||
expect_unreal_good(& ctx, txt("unreal"));
|
||||
deinit(& ctx);
|
||||
expect_unreal_bad(txt("unreal-at"));
|
||||
|
||||
if (g_failures != 0) { log_fmt("dogfood parse fixtures failed: %d\n", g_failures); return 1; }
|
||||
log_fmt("dogfood parse fixtures passed\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user