{"id":193,"date":"2011-03-13T08:00:00","date_gmt":"2011-03-13T08:00:00","guid":{"rendered":"https:\/\/pagan-gerbil.net\/?p=193"},"modified":"2011-03-13T08:00:00","modified_gmt":"2011-03-13T08:00:00","slug":"learning-unit-testing-x-finishing-hiding","status":"publish","type":"post","link":"https:\/\/www.pagan-gerbil.net\/?p=193","title":{"rendered":"Learning Unit Testing X &#8211; Finishing Hiding"},"content":{"rendered":"<p>Last time, I got the tests for Charging out of the way, and got through a raft of simple checks for Hiding. This time, a few of the more complicated checks.<\/p>\n<p>First off, a model can move around while hiding as long as it remains out of sight. I\u2019m not sure how to be checking every point along the move, but I can check at the end of the movement whether it\u2019s still out of sight.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_ThrowsExceptionIfInSightAfterMove()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel });\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\ntestModel.Movement = 4;\n<span style=\"color: blue\">bool <\/span>exceptionThrown = <span style=\"color: blue\">false<\/span>;\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(0);\ntestModel.Hide();\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(1);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(testModel.IsHiding);\n<span style=\"color: blue\">try\n<\/span>{\ntestModel.MoveModel(4, 0, 0);\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\nexceptionThrown = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(enemyModel, ex.EnemyModels[0]);\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(exceptionThrown);\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n}<\/pre>\n<p>The best way to check this is probably to call the Hide method at the end of MoveModel \u2013 any change in the model\u2019s visibility will be picked up. Code re-use: excellent!<\/p>\n<pre class=\"code\"><span style=\"color: blue\">if <\/span>(<span style=\"color: blue\">this<\/span>.IsHiding)\n{\n<span style=\"color: blue\">this<\/span>.Hide();\n}<\/pre>\n<p>But I still don\u2019t get a pass&#8230; I also need to set IsHiding to false in the Hide method, when it throws an exception. Then the test goes green.<\/p>\n<p>The next test is that after an enemy model has moved, it might force a model to stop being hidden. I will keep the current action of throwing an exception \u2013 this will let the imaginary UI show that hiding has ceased.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_StopsHidingIfInSightAfterEnemyMove()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel });\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\nenemyModel.Movement = 4;\n<span style=\"color: blue\">bool <\/span>exceptionThrown = <span style=\"color: blue\">false<\/span>;\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(0);\ntestModel.Hide();\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(1);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(testModel.IsHiding);\n<span style=\"color: blue\">try\n<\/span>{\nenemyModel.MoveModel(4, 0, 0);\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\nexceptionThrown = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(enemyModel, ex.EnemyModels[0]);\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(exceptionThrown);\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n}<\/pre>\n<p>The code to pass this test should be just adding the following check to the end of MoveModel (as long as Hide is added to the IModel interface).<\/p>\n<pre class=\"code\"><span style=\"color: blue\">foreach <\/span>(<span style=\"color: #2b91af\">IModel <\/span>enemyModel <span style=\"color: blue\">in <\/span>(<span style=\"color: blue\">from <\/span>models <span style=\"color: blue\">in <\/span>_gameManager.Models\n<span style=\"color: blue\">where <\/span>models.Player != <span style=\"color: blue\">this<\/span>.Player\n<span style=\"color: blue\">select <\/span>models))\n{\nenemyModel.Hide();\n}<\/pre>\n<p>But this doesn\u2019t work \u2013 not only does it not work, but it breaks other tests! Now, Charge_SetsIsChargingFlag, MoveModel_CannotMoveFurtherThanModelsMovement and NewTurn_SetsIsChargingToFalse throw exceptions and this test fails on the penultimate assert that the exception was thrown. I believe the error with this test is that the Mock GameManager I\u2019m using is only returning the enemyModel \u2013 not the testModel. When I added the testModel to the setup, this test at least passes. The other tests all throw exceptions. This is probably due to the fact that the GameManager is not being correctly set up in each case, to return an empty List&lt;IModel&gt; \u2013 as a mock object, it returns null instead and the above code to check for other models fails when passed a null.<\/p>\n<p>By adding in the required setup line to each of those tests, I get 31 passes again.<\/p>\n<p>Finally, a model is automatically forced out of hiding if an enemy model is within it\u2019s Initiative range of the hiding model. This one needs to be checked when the model chooses to hide, and also whenever it moves or the enemy model moves. Since all three of these cause the Hide method to be called, that should probably be where it sits. The following tests should cover off those three situations:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_CannotHideIfEnemyInInitiativeRange()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(0);\ntestModel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 0, 0);\nenemyModel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(1, 0, 0);\nenemyModel.Initiative = 2;\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel, testModel });\n<span style=\"color: blue\">bool <\/span>correctExceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\ntestModel.Hide();\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\ncorrectExceptionThrown = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(enemyModel, ex.EnemyModels[0]);\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(correctExceptionThrown);\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>MoveModel_StopHidingIfModelMovesIntoEnemyInitiativeRange()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(0);\ntestModel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 0, 0);\nenemyModel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(5, 0, 0);\nenemyModel.Initiative = 3;\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel, testModel });\ntestModel.IsHiding = <span style=\"color: blue\">true<\/span>;\ntestModel.Movement = 4;\n<span style=\"color: blue\">bool <\/span>correctExceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\ntestModel.MoveModel(4, 0, 0);\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\ncorrectExceptionThrown = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(enemyModel, ex.EnemyModels[0]);\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(correctExceptionThrown);\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>MoveModel_StopHidingIfEnemyMovesWithinInitiativeRange()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(0);\ntestModel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(5, 0, 0);\nenemyModel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 0, 0);\nenemyModel.Initiative = 3;\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel, testModel });\ntestModel.IsHiding = <span style=\"color: blue\">true<\/span>;\nenemyModel.Movement = 4;\n<span style=\"color: blue\">bool <\/span>correctExceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\nenemyModel.MoveModel(4, 0, 0);\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\ncorrectExceptionThrown = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(enemyModel, ex.EnemyModels[0]);\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(correctExceptionThrown);\n}<\/pre>\n<p>The passing code sits in Hide, and is very pleasantly simple. Hide becomes very long:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public void <\/span>Hide()\n{\n<span style=\"color: blue\">if <\/span>(<span style=\"color: blue\">this<\/span>.IsCharging || <span style=\"color: blue\">this<\/span>.IsRunning)\n{\n<span style=\"color: #2b91af\">HidingException <\/span>ex = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">HidingException<\/span>(<span style=\"color: #a31515\">\"Cannot hide if charged or ran this turn.\"<\/span>);\n<span style=\"color: blue\">throw <\/span>ex;\n}\n<span style=\"color: blue\">else\n<\/span>{\n<span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt; enemyModels = (<span style=\"color: blue\">from <\/span>models <span style=\"color: blue\">in this<\/span>._gameManager.Models\n<span style=\"color: blue\">where <\/span>models.Player != <span style=\"color: blue\">this<\/span>.Player\n&amp;&amp; (<span style=\"color: blue\">this<\/span>._objectManager.GetLineOfSight(models, <span style=\"color: blue\">this<\/span>) &gt; 0.6 || <span style=\"color: blue\">this<\/span>.GetDistanceFrom(models.Location.X, models.Location.Y, models.Location.Z) &lt;= models.Initiative)\n<span style=\"color: blue\">select <\/span>models).ToList();\n<span style=\"color: blue\">if <\/span>(enemyModels.Count &gt; 0)\n{\n<span style=\"color: blue\">this<\/span>.IsHiding = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">HidingException <\/span>ex = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">HidingException<\/span>(<span style=\"color: #a31515\">\"Cannot hide in sight or Initiative range of enemy models.\"<\/span>);\nex.EnemyModels = enemyModels;\n<span style=\"color: blue\">throw <\/span>ex;\n}\n<span style=\"color: blue\">else\n<\/span>{\n<span style=\"color: blue\">this<\/span>.IsHiding = <span style=\"color: blue\">true<\/span>;\n}\n}\n}<\/pre>\n<p>But this breaks several other tests. The reason is that some of the previously written tests are not setting locations for the enemy and test models, and the distance between them (zero) is always equal to or less than the default Initiative value (also zero). Changing the tests to give them a bit of space fixes this problem.<\/p>\n<p>Since a model can remain hidden for several successive turns, it doesn\u2019t need to reset the IsHiding flag \u2013 Hiding for all hidden models is checked whenever a model is moved, so it will be taken out of hiding when a player wishes or when it is chosen.<\/p>\n<p>Next time, I move off of page 11, but I\u2019m not sure where to yet&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, I got the tests for Charging out of the way, and got through a raft of simple checks for Hiding. This time, a few of the more complicated checks. First off, a model can move around while hiding as long as it remains out of sight. I\u2019m not sure how to be checking &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.pagan-gerbil.net\/?p=193\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learning Unit Testing X &#8211; Finishing Hiding&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[43,62,63,64],"series":[73],"_links":{"self":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/193"}],"collection":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=193"}],"version-history":[{"count":0,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/193\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=193"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}