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
|
parser_bounds
|
||||||
lexer_failures
|
lexer_failures
|
||||||
parse_body_messages
|
parse_body_messages
|
||||||
|
dogfood_parse
|
||||||
clang
|
clang
|
||||||
msvc : By default this project builds with clang, specifying msvc will build with MSVC.
|
msvc : By default this project builds with clang, specifying msvc will build with MSVC.
|
||||||
debug
|
debug
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ Push-Location $path_root
|
|||||||
[bool] $parser_bounds = $false
|
[bool] $parser_bounds = $false
|
||||||
[bool] $lexer_failures = $false
|
[bool] $lexer_failures = $false
|
||||||
[bool] $parse_body_messages = $false
|
[bool] $parse_body_messages = $false
|
||||||
|
[bool] $dogfood_parse = $false
|
||||||
|
|
||||||
[array] $vendors = @( "clang", "msvc" )
|
[array] $vendors = @( "clang", "msvc" )
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ if ( $args ) { $args | ForEach-Object {
|
|||||||
"parser_bounds" { $parser_bounds = $true }
|
"parser_bounds" { $parser_bounds = $true }
|
||||||
"lexer_failures" { $lexer_failures = $true }
|
"lexer_failures" { $lexer_failures = $true }
|
||||||
"parse_body_messages" { $parse_body_messages = $true }
|
"parse_body_messages" { $parse_body_messages = $true }
|
||||||
|
"dogfood_parse" { $dogfood_parse = $true }
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
#endregion Arguments
|
#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 $parser_bounds -eq $false
|
||||||
$cannot_build = $cannot_build -and $lexer_failures -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 $parse_body_messages -eq $false
|
||||||
|
$cannot_build = $cannot_build -and $dogfood_parse -eq $false
|
||||||
if ( $cannot_build ) {
|
if ( $cannot_build ) {
|
||||||
Stop-stage "No build target specified"
|
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
|
$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
|
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
|
#endregion Building
|
||||||
|
|
||||||
pop-location # $path_root
|
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_parser_bounds_build = Join-Path $path_test "parser_bounds\build"
|
||||||
$path_lexer_failures_build = Join-Path $path_test "lexer_failures\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_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_x64 = Join-Path $path_root x64
|
||||||
$path_release = Join-Path $path_root release
|
$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 ) {
|
if ( Test-Path $path_parse_body_messages_build ) {
|
||||||
Remove-Item $path_parse_body_messages_build -Recurse -Verbose
|
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) {
|
if ( Test-Path $path_x64) {
|
||||||
Remove-Item $path_x64 -Recurse -Verbose
|
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