// Reimplementations of the following tests from Flecs: // https://github.com/SanderMertens/flecs/blob/master/test/api/src/Entity.c const std = @import("std"); const expect = std.testing.expect; const expectFmt = std.testing.expectFmt; const expectEqual = std.testing.expectEqual; const expectEqualStrings = std.testing.expectEqualStrings; const expectError = std.testing.expectError; const util = @import("./util.zig"); const FlecsError = @import("../src/error.zig").FlecsError; const flecs = @import("../src/main.zig"); const c = flecs.c; const context = flecs.Context(void); const Entity = context.Entity; const Path = context.Path; const World = context.World; test "Entity_init_id" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const e = try world.entity(.{}, .{}); try expect(c.ecs_get_type(world.raw, e.raw) == null); } test "Entity_init_id_name" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const e = try world.entity(.{ .name = "foo" }, .{}); try expectEqualStrings("foo", e.getName().?); const path2 = try e.getPath(flecs.allocator); defer path2.deinit(); try expectFmt("foo", "{}", .{path2}); } test "Entity_init_id_path" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const p = try Path.fromString("parent.child", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); } test "Entity_init_id_add_1_comp" { const TagA = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); const e = try world.entity(.{}, .{TagA}); try expect(e.has(TagA)); } test "Entity_init_id_add_2_comp" { const TagA = struct {}; const TagB = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); _ = try world.tag(TagB); const e = try world.entity(.{}, .{ TagA, TagB }); try expect(e.has(TagA)); try expect(e.has(TagB)); } test "Entity_init_id_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{}, .{}); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const e = try world.entity(.{}, .{}); try expect(e.has(.{ c.EcsChildOf, scope })); } test "Entity_init_id_name_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const e = try world.entity(.{ .name = "child" }, .{}); try expect(e.has(.{ c.EcsChildOf, scope })); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); } test "Entity_init_id_path_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const p = try Path.fromString("child.grandchild", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("grandchild", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child.grandchild", "{}", .{path}); } test "Entity_init_id_fullpath_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const p = try Path.fromString("::parent.child.grandchild", .{ .root_sep = "::", .sep = "." }, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("grandchild", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child.grandchild", "{}", .{path}); } test "Entity_init_id_fullpath_w_scope_existing" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const p = try Path.fromString("::parent.child.grandchild", .{ .root_sep = "::", .sep = "." }, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); const r = try world.entity(.{ .path = p }, .{}); try expectEqual(e, r); try expectEqualStrings("grandchild", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child.grandchild", "{}", .{path}); } test "Entity_init_id_name_1_comp" { const TagA = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); const e = try world.entity(.{ .name = "foo" }, .{TagA}); try expect(e.has(TagA)); try expectEqualStrings("foo", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("foo", "{}", .{path}); } test "Entity_init_id_name_2_comp" { const TagA = struct {}; const TagB = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); _ = try world.tag(TagB); const e = try world.entity(.{ .name = "foo" }, .{ TagA, TagB }); try expect(e.has(TagA)); try expectEqualStrings("foo", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("foo", "{}", .{path}); } test "Entity_init_id_name_2_comp_w_scope" { const TagA = struct {}; const TagB = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); _ = try world.tag(TagB); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const e = try world.entity(.{ .name = "child" }, .{ TagA, TagB }); try expect(e.has(TagA)); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); } test "Entity_id_add_1_comp" { const TagA = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); const e = try world.entity(.{}, .{}); const r = try world.entity(.{ .id = e }, .{TagA}); try expectEqual(e, r); try expect(e.has(TagA)); } test "Entity_id_add_2_comp" { const TagA = struct {}; const TagB = struct {}; flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); _ = try world.tag(TagA); _ = try world.tag(TagB); const e = try world.entity(.{}, .{}); const r = try world.entity(.{ .id = e }, .{ TagA, TagB }); try expectEqual(e, r); try expect(e.has(TagA)); try expect(e.has(TagB)); } test "Entity_init_id_path_w_sep" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const p = try Path.fromString("parent::child", .{ .root_sep = null, .sep = "::" }, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); } test "Entity_find_id_name" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const e = try world.entity(.{ .name = "foo" }, .{}); try expectEqualStrings("foo", e.getName().?); const r = try world.entity(.{ .name = "foo" }, .{}); try expectEqual(e, r); } test "Entity_find_w_existing_id_name" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const id = try world.entity(.{}, .{}); const e = try world.entity(.{ .id = id, .name = "foo" }, .{}); try expectEqual(e, id); try expectEqualStrings("foo", e.getName().?); const r = try world.entity(.{ .name = "foo" }, .{}); try expectEqual(e, r); } test "Entity_find_id_name_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const e = try world.entity(.{ .name = "child" }, .{}); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); const r = try world.entity(.{ .name = "child" }, .{}); try expectEqual(e, r); } test "Entity_find_id_path" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const p = try Path.fromString("parent.child", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); const r = try world.entity(.{ .path = p }, .{}); try expectEqual(e, r); } test "Entity_find_id_path_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const p = try Path.fromString("child.grandchild", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("grandchild", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child.grandchild", "{}", .{path}); const r = try world.entity(.{ .path = p }, .{}); try expectEqual(e, r); } test "Entity_find_id_name_match" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const e = try world.entity(.{ .name = "foo" }, .{}); try expectEqualStrings("foo", e.getName().?); const r = try world.entity(.{ .id = e, .name = "foo" }, .{}); try expectEqual(e, r); } test "Entity_find_id_name_match_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const e = try world.entity(.{ .name = "child" }, .{}); try expectEqualStrings("child", e.getName().?); const path = try e.getPath(flecs.allocator); defer path.deinit(); try expectFmt("parent.child", "{}", .{path}); const r1 = try world.entity(.{ .id = e, .name = "child" }, .{}); try expectEqual(e, r1); _ = world.setScope(null); const p2 = try Path.fromString("parent.child", null, flecs.allocator); defer p2.deinit(); const r2 = try world.entity(.{ .id = e, .path = p2 }, .{}); try expectEqual(e, r2); } test "Entity_find_id_path_match" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const p = try Path.fromString("parent.child", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("child", e.getName().?); const r = try world.entity(.{ .id = e, .path = p }, .{}); try expectEqual(e, r); } test "Entity_find_id_path_match_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const p = try Path.fromString("child.grandchild", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("grandchild", e.getName().?); const r1 = try world.entity(.{ .id = e, .path = p }, .{}); try expectEqual(e, r1); _ = world.setScope(null); const p2 = try Path.fromString("parent.child.grandchild", null, flecs.allocator); defer p2.deinit(); const r2 = try world.entity(.{ .id = e, .path = p2 }, .{}); try expectEqual(e, r2); } test "Entity_find_id_name_mismatch" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const e = try world.entity(.{ .name = "foo" }, .{}); try expectEqualStrings("foo", e.getName().?); _ = try world.entity(.{ .name = "bar" }, .{}); _ = c.ecs_log_set_level(-4); const r = world.entity(.{ .id = e, .name = "bar" }, .{}); try expectError(FlecsError.Unknown, r); } test "Entity_find_id_name_mismatch_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const e = try world.entity(.{ .name = "child" }, .{}); try expectEqualStrings("child", e.getName().?); _ = c.ecs_log_set_level(-4); const r = world.entity(.{ .id = e, .name = "parent" }, .{}); try expectError(FlecsError.Unknown, r); } test "Entity_find_id_path_mismatch" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const p = try Path.fromString("parent.child", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("child", e.getName().?); _ = c.ecs_log_set_level(-4); const p2 = try Path.fromString("parent.foo", null, flecs.allocator); defer p2.deinit(); const r = world.entity(.{ .id = e, .path = p2 }, .{}); try expectError(FlecsError.Unknown, r); } test "Entity_find_id_path_mismatch_w_scope" { flecs.init(std.testing.allocator); var world = try World.initMinimal(); defer world.deinit(); const scope = try world.entity(.{ .name = "parent" }, .{}); try expectEqualStrings("parent", scope.getName().?); _ = world.setScope(scope); try expectEqual(scope, world.getScope().?); const p = try Path.fromString("child.grandchild", null, flecs.allocator); defer p.deinit(); const e = try world.entity(.{ .path = p }, .{}); try expectEqualStrings("grandchild", e.getName().?); const p2 = try Path.fromString("child.foo", null, flecs.allocator); defer p2.deinit(); _ = try world.entity(.{ .path = p2 }, .{}); _ = c.ecs_log_set_level(-4); const p3 = try Path.fromString("child.foo", null, flecs.allocator); defer p3.deinit(); const r = world.entity(.{ .id = e, .path = p3 }, .{}); try expectError(FlecsError.Unknown, r); }