public function test_hierarchical_deserialization_with_container_template()
 {
     $t = new Seriplater(new Rule());
     $idResolver = new IdResolver();
     $idFactory = new IdFactory();
     $hier = new HierarchicalTemplate($idResolver);
     $serializer = new GenericSerializer($idFactory);
     $deserializer = new GenericDeserializer($idResolver);
     $topTemplate = new ContainerTemplate($idFactory, $idResolver, ["id" => $t->id("tops"), "foos" => $t->hasMany("foos"), "bars" => $t->hasMany("bars")], 1);
     $fooRepository = Mockery::mock("Prewk\\Seriplating\\Contracts\\RepositoryInterface");
     $fooTemplate = new SeriplatingTemplate($serializer, $deserializer, $fooRepository, ["id" => $t->id("foos"), "top_id" => $t->inherits("id"), "val" => $t->value(), "sort_order" => $t->increments()]);
     $barRepository = Mockery::mock("Prewk\\Seriplating\\Contracts\\RepositoryInterface");
     $barTemplate = new SeriplatingTemplate($serializer, $deserializer, $barRepository, ["id" => $t->id("bars"), "val" => $t->value(), "bazes" => $t->hasMany("bazes"), "top_id" => $t->conditions("val", ["bar" => $t->inherits("id")])]);
     $bazRepository = Mockery::mock("Prewk\\Seriplating\\Contracts\\RepositoryInterface");
     $bazTemplate = new SeriplatingTemplate($serializer, $deserializer, $bazRepository, ["id" => $t->id("bazes"), "val" => $t->value(), "bar_id" => $t->inherits("id"), "top_id" => $t->inherits("top_id"), "foo_id" => $t->references("foos")]);
     $serialization = ["_id" => $idFactory->get("tops", 1), "foos" => [["_id" => $idFactory->get("foos", 2), "val" => "ipsum"], ["_id" => $idFactory->get("foos", 3), "val" => "foo"]], "bars" => [["_id" => $idFactory->get("bars", 4), "val" => "bar", "bazes" => [["_id" => $idFactory->get("bazes", 5), "val" => "baz", "foo_id" => ["_ref" => $idFactory->get("foos", 2)]]]]]];
     $expectedCreatedEntityData = ["id" => 1, "foos" => [["id" => 2, "val" => "ipsum", "top_id" => 1, "sort_order" => 0], ["id" => 3, "val" => "foo", "top_id" => 1, "sort_order" => 1]], "bars" => [["id" => 4, "val" => "bar", "bazes" => [["id" => 5, "val" => "baz", "top_id" => 1, "bar_id" => 4, "foo_id" => 0]], "top_id" => 1]]];
     $fooRepository->shouldReceive("create")->once()->with(["val" => "ipsum", "top_id" => 1, "sort_order" => 0])->andReturn(["id" => 2, "val" => "ipsum", "top_id" => 1, "sort_order" => 0])->shouldReceive("create")->once()->with(["val" => "foo", "top_id" => 1, "sort_order" => 1])->andReturn(["id" => 3, "val" => "foo", "top_id" => 1, "sort_order" => 1]);
     $barRepository->shouldReceive("create")->once()->with(["val" => "bar", "top_id" => 1])->andReturn(["id" => 4, "val" => "bar", "top_id" => 1]);
     $bazRepository->shouldReceive("create")->once()->with(["val" => "baz", "top_id" => 1, "bar_id" => 4, "foo_id" => 0])->andReturn(["id" => 5, "val" => "baz", "top_id" => 1, "bar_id" => 4, "foo_id" => 0])->shouldReceive("update")->once()->with(5, ["foo_id" => 2]);
     $hier->register($topTemplate)->register($fooTemplate)->register($barTemplate)->register($bazTemplate);
     $entityData = $hier->deserialize("tops", $serialization);
     $this->assertEquals($expectedCreatedEntityData, $entityData);
 }
 public function test_self_referential_recursion()
 {
     $t = new Seriplater(new Rule());
     $menuEntity = ["id" => 1, "locale" => "en-US", "menu_items" => [["id" => 1, "menu_id" => 1, "parent_id" => 0, "sort_order" => 0], ["id" => 2, "menu_id" => 1, "parent_id" => 0, "sort_order" => 1], ["id" => 3, "menu_id" => 1, "parent_id" => 2, "sort_order" => 5]]];
     $menuTemplate = ["id" => $t->id("menus"), "locale" => $t->value(), "menu_items" => $t->hasMany("menu_items")];
     $menuItemTemplate = ["id" => $t->id("menu_items"), "menu_id" => $t->inherits("id"), "parent_id" => $t->references("menu_items", 0), "sort_order" => $t->value()];
     $idFactory = new IdFactory();
     $idResolver = new IdResolver();
     $genSerializer = new GenericSerializer($idFactory);
     $genDeserializer = new GenericDeserializer($idResolver);
     // Menu
     $menuRepo = Mockery::mock("Prewk\\Seriplating\\Contracts\\RepositoryInterface");
     $menu = new SeriplatingTemplate($genSerializer, $genDeserializer, $menuRepo, $menuTemplate);
     // Menu item
     $menuItemRepo = Mockery::mock("Prewk\\Seriplating\\Contracts\\RepositoryInterface");
     $menuItem = new SeriplatingTemplate($genSerializer, $genDeserializer, $menuItemRepo, $menuItemTemplate);
     $hier = new HierarchicalTemplate($idResolver);
     $hier->register($menu)->register($menuItem);
     $serialization = $hier->serialize("menus", $menuEntity);
     $menuRepo->shouldReceive("create")->once()->with(["locale" => "en-US"])->andReturn(["id" => 1, "locale" => "en-US"]);
     $menuItemRepo->shouldReceive("create")->once()->with(["menu_id" => 1, "parent_id" => 0, "sort_order" => 0])->andReturn(["id" => 1, "menu_id" => 1, "parent_id" => 0, "sort_order" => 0])->shouldReceive("create")->once()->with(["menu_id" => 1, "parent_id" => 0, "sort_order" => 5])->andReturn(["id" => 3, "menu_id" => 1, "parent_id" => 0, "sort_order" => 5])->shouldReceive("create")->once()->with(["menu_id" => 1, "parent_id" => 0, "sort_order" => 1])->andReturn(["id" => 2, "menu_id" => 1, "parent_id" => 0, "sort_order" => 1])->shouldReceive("update")->once()->with(1, ["parent_id" => 0])->andReturn(["id" => 1, "menu_id" => 1, "parent_id" => 0, "sort_order" => 0])->shouldReceive("update")->once()->with(2, ["parent_id" => 0])->andReturn(["id" => 2, "menu_id" => 1, "parent_id" => 0, "sort_order" => 1])->shouldReceive("update")->once()->with(3, ["parent_id" => 2])->andReturn(["id" => 3, "menu_id" => 1, "parent_id" => 2, "sort_order" => 0]);
     $deserialized = $hier->deserialize("menus", $serialization);
 }