High-level wrapper around Flecs, a powerful ECS (Entity Component System) library, written in Zig language
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

627 lines
18 KiB

// Reimplementations of the following tests from Flecs:
// https://github.com/SanderMertens/flecs/blob/master/test/api/src/Entity.c
const std = @import("std");
const alloc = std.testing.allocator;
const expect = @import("../expect.zig");
const util = @import("../util.zig");
const flecszigble = @import("../../main.zig");
const FlecsError = flecszigble.FlecsError;
const Path = flecszigble.Path;
const c = flecszigble.c;
const flecs = flecszigble.flecs;
const ChildOf = flecs.core.ChildOf;
const Context = flecszigble.Context(void);
const Entity = Context.Entity;
const World = Context.World;
test "Entity_init_id" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e = try world.entity(.{}, .{});
try expect.null(c.ecs_get_type(world.raw, e.raw));
}
test "Entity_init_id_name" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("foo", "{}", .{path});
}
test "Entity_init_id_path" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e_parts = Path.buildParts(.{ "parent", "child" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
}
test "Entity_init_id_add_1_comp" {
const TagA = struct {};
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
_ = try world.tag(TagA);
const e = try world.entity(.{}, .{TagA});
try expect.true(e.has(TagA));
}
test "Entity_init_id_add_2_comp" {
const TagA = struct {};
const TagB = struct {};
flecszigble.init(alloc);
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.true(e.has(TagA));
try expect.true(e.has(TagB));
}
test "Entity_init_id_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{}, .{});
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e = try world.entity(.{}, .{});
try expect.true(e.has(.{ ChildOf, scope }));
}
test "Entity_init_id_name_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e = try world.entity(.{ .name = "child" }, .{});
try expect.true(e.has(.{ ChildOf, scope }));
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
}
test "Entity_init_id_path_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e_parts = Path.buildParts(.{ "child", "grandchild" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("grandchild", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child.grandchild", "{}", .{path});
}
test "Entity_init_id_fullpath_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const p = try Path.fromString("::parent.child.grandchild", .{ .root_sep = "::", .sep = "." }, flecszigble.allocator);
defer p.deinit();
const e = try world.entity(.{ .path = p }, .{});
try expect.equal("grandchild", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child.grandchild", "{}", .{path});
}
test "Entity_init_id_fullpath_w_scope_existing" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const p = try Path.fromString("::parent.child.grandchild", .{ .root_sep = "::", .sep = "." }, flecszigble.allocator);
defer p.deinit();
const e = try world.entity(.{ .path = p }, .{});
const r = try world.entity(.{ .path = p }, .{});
try expect.equal(e, r);
try expect.equal("grandchild", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child.grandchild", "{}", .{path});
}
test "Entity_init_id_name_1_comp" {
const TagA = struct {};
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
_ = try world.tag(TagA);
const e = try world.entity(.{ .name = "foo" }, .{TagA});
try expect.true(e.has(TagA));
try expect.equal("foo", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("foo", "{}", .{path});
}
test "Entity_init_id_name_2_comp" {
const TagA = struct {};
const TagB = struct {};
flecszigble.init(alloc);
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.true(e.has(TagA));
try expect.equal("foo", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("foo", "{}", .{path});
}
test "Entity_init_id_name_2_comp_w_scope" {
const TagA = struct {};
const TagB = struct {};
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
_ = try world.tag(TagA);
_ = try world.tag(TagB);
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e = try world.entity(.{ .name = "child" }, .{ TagA, TagB });
try expect.true(e.has(TagA));
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
}
test "Entity_id_add_1_comp" {
const TagA = struct {};
flecszigble.init(alloc);
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 expect.equal(e, r);
try expect.true(e.has(TagA));
}
test "Entity_id_add_2_comp" {
const TagA = struct {};
const TagB = struct {};
flecszigble.init(alloc);
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 expect.equal(e, r);
try expect.true(e.has(TagA));
try expect.true(e.has(TagB));
}
test "Entity_init_id_path_w_sep" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const p = try Path.fromString("parent::child", .{ .root_sep = null, .sep = "::" }, flecszigble.allocator);
defer p.deinit();
const e = try world.entity(.{ .path = p }, .{});
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
}
test "Entity_find_id_name" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", e.name());
const r = try world.entity(.{ .name = "foo" }, .{});
try expect.equal(e, r);
}
test "Entity_find_w_existing_id_name" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const id = try world.entity(.{}, .{});
const e = try world.entity(.{ .id = id, .name = "foo" }, .{});
try expect.equal(e, id);
try expect.equal("foo", e.name());
const r = try world.entity(.{ .name = "foo" }, .{});
try expect.equal(e, r);
}
test "Entity_find_id_name_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e = try world.entity(.{ .name = "child" }, .{});
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
const r = try world.entity(.{ .name = "child" }, .{});
try expect.equal(e, r);
}
test "Entity_find_id_path" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e_parts = Path.buildParts(.{ "parent", "child" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
const r = try world.entity(.{ .path = e_path }, .{});
try expect.equal(e, r);
}
test "Entity_find_id_path_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e_parts = Path.buildParts(.{ "child", "grandchild" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("grandchild", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child.grandchild", "{}", .{path});
const r = try world.entity(.{ .path = e_path }, .{});
try expect.equal(e, r);
}
test "Entity_find_id_name_match" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", e.name());
const r = try world.entity(.{ .id = e, .name = "foo" }, .{});
try expect.equal(e, r);
}
test "Entity_find_id_name_match_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e = try world.entity(.{ .name = "child" }, .{});
try expect.equal("child", e.name());
const path = try e.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.child", "{}", .{path});
const r1 = try world.entity(.{ .id = e, .name = "child" }, .{});
try expect.equal(e, r1);
_ = world.setScope(null);
const r2_parts = Path.buildParts(.{ "parent", "child" });
const r2_path = Path.fromParts(false, &r2_parts);
const r2 = try world.entity(.{ .id = e, .path = r2_path }, .{});
try expect.equal(e, r2);
}
test "Entity_find_id_path_match" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e_parts = Path.buildParts(.{ "parent", "child" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("child", e.name());
const r = try world.entity(.{ .id = e, .path = e_path }, .{});
try expect.equal(e, r);
}
test "Entity_find_id_path_match_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e_parts = Path.buildParts(.{ "child", "grandchild" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("grandchild", e.name());
const r1 = try world.entity(.{ .id = e, .path = e_path }, .{});
try expect.equal(e, r1);
_ = world.setScope(null);
const r2_parts = Path.buildParts(.{ "parent", "child", "grandchild" });
const r2_path = Path.fromParts(false, &r2_parts);
const r2 = try world.entity(.{ .id = e, .path = r2_path }, .{});
try expect.equal(e, r2);
}
test "Entity_find_id_name_mismatch" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", e.name());
_ = try world.entity(.{ .name = "bar" }, .{});
const prev_log_level = c.ecs_log_set_level(-4);
defer _ = c.ecs_log_set_level(prev_log_level);
const r = world.entity(.{ .id = e, .name = "bar" }, .{});
try expect.err(FlecsError.Unknown, r);
}
test "Entity_find_id_name_mismatch_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e = try world.entity(.{ .name = "child" }, .{});
try expect.equal("child", e.name());
const prev_log_level = c.ecs_log_set_level(-4);
defer _ = c.ecs_log_set_level(prev_log_level);
const r = world.entity(.{ .id = e, .name = "parent" }, .{});
try expect.err(FlecsError.Unknown, r);
}
test "Entity_find_id_path_mismatch" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e_parts = Path.buildParts(.{ "parent", "child" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("child", e.name());
const prev_log_level = c.ecs_log_set_level(-4);
defer _ = c.ecs_log_set_level(prev_log_level);
const r_parts = Path.buildParts(.{ "parent", "foo" });
const r_path = Path.fromParts(false, &r_parts);
const r = world.entity(.{ .id = e, .path = r_path }, .{});
try expect.err(FlecsError.Unknown, r);
}
test "Entity_find_id_path_mismatch_w_scope" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const scope = try world.entity(.{ .name = "parent" }, .{});
try expect.equal("parent", scope.name());
_ = world.setScope(scope);
try expect.equal(scope, world.scope());
const e_parts = Path.buildParts(.{ "child", "grandchild" });
const e_path = Path.fromParts(false, &e_parts);
const e = try world.entity(.{ .path = e_path }, .{});
try expect.equal("grandchild", e.name());
const unnamed_parts = Path.buildParts(.{ "child", "foo" });
const unnamed_path = Path.fromParts(false, &unnamed_parts);
_ = try world.entity(.{ .path = unnamed_path }, .{});
const prev_log_level = c.ecs_log_set_level(-4);
defer _ = c.ecs_log_set_level(prev_log_level);
const r = world.entity(.{ .id = e, .path = unnamed_path }, .{});
try expect.err(FlecsError.Unknown, r);
}
test "Entity_find_id_add_1_comp" {
const TagA = struct {};
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
_ = try world.tag(TagA);
const e = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", e.name());
const r = try world.entity(.{ .name = "foo" }, .{TagA});
try expect.equal(e, r);
try expect.true(e.has(TagA));
}
test "Entity_find_id_add_2_comp" {
const TagA = struct {};
const TagB = struct {};
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
_ = try world.tag(TagA);
_ = try world.tag(TagB);
const e = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", e.name());
const r = try world.entity(.{ .name = "foo" }, .{ TagA, TagB });
try expect.equal(e, r);
try expect.true(e.has(TagA));
try expect.true(e.has(TagB));
}
test "Entity_init_w_scope_name" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
_ = try world.entity(.{ .name = "parent" }, .{});
const foo_parts = Path.buildParts(.{ "parent", "foo" });
const foo_path = Path.fromParts(false, &foo_parts);
const foo = try world.entity(.{ .path = foo_path }, .{});
_ = world.setScope(foo);
const child = try world.entity(.{ .name = "foo" }, .{});
try expect.equal("foo", child.name());
const path = try child.path(flecszigble.allocator);
defer path.deinit();
try expect.fmt("parent.foo.foo", "{}", .{path});
}
test "Entity_init_w_core_name" {
flecszigble.init(alloc);
var world = try World.initMinimal();
defer world.deinit();
const e = try world.entity(.{ .name = "Prefab" }, .{});
try expect.false(c.EcsPrefab == e.raw);
}