ServiceDescriptionTest.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. /*
  3. * Copyright 2017 Aaron Scherer
  4. *
  5. * This source file is subject to the license that is bundled
  6. * with this source code in the file LICENSE
  7. *
  8. * @package restcord/restcord
  9. * @copyright Aaron Scherer 2017
  10. * @license MIT
  11. */
  12. namespace RestCord\Tests;
  13. use GuzzleHttp\Command\Result;
  14. use PHPUnit\Framework\TestCase;
  15. use RestCord\DiscordClient;
  16. /**
  17. * @author Aaron Scherer <aequasi@gmail.com>
  18. *
  19. * ServiceDescriptionTest Class
  20. */
  21. class ServiceDescriptionTest extends TestCase
  22. {
  23. /**
  24. * @var array
  25. */
  26. public $description;
  27. /**
  28. * @var DiscordClient
  29. */
  30. public $client;
  31. public function setUp()
  32. {
  33. $this->description = json_decode(
  34. file_get_contents(__DIR__.'/../src/Resources/service_description-v6.json'),
  35. true
  36. );
  37. $this->client = new DiscordClient(['token' => 'fake-token']);
  38. }
  39. public function testBaseUri()
  40. {
  41. $this->assertEquals('https://discordapp.com/api/v6', $this->description['baseUri']);
  42. }
  43. public function testVersion()
  44. {
  45. $this->assertEquals('6', $this->description['version']);
  46. }
  47. public function testOperationResources()
  48. {
  49. foreach ($this->description['operations'] as $resource => $operations) {
  50. $resource = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $resource)));
  51. $class = '\\RestCord\\Interfaces\\'.ucwords($resource);
  52. $this->assertTrue(interface_exists($class), 'Could not find interface: '.$class);
  53. $refl = new \ReflectionClass($class);
  54. foreach ($operations as $method => $operation) {
  55. $this->assertTrue($refl->hasMethod($method));
  56. $reflMethod = $refl->getMethod($method);
  57. if (isset($operation['responseTypes']) && count($operation['responseTypes']) >= 1) {
  58. $firstType = $operation['responseTypes'][0]['type'];
  59. $array = stripos($firstType, 'Array<') !== false;
  60. if ($array) {
  61. $firstType = substr($firstType, 6, -1);
  62. }
  63. $firstType = explode('/', $firstType);
  64. $returnType = sprintf(
  65. '\\RestCord\\Model\\%s\\%s',
  66. str_replace(
  67. ' ',
  68. '',
  69. ucwords(str_replace('-', ' ', $firstType[0]))
  70. ),
  71. str_replace(
  72. ' ',
  73. '',
  74. ucwords(str_replace('-', ' ', $firstType[1]))
  75. )
  76. );
  77. $returnType = $this->mapBadDocs($returnType);
  78. if (!class_exists($returnType)) {
  79. $returnType = '\\'.Result::class;
  80. }
  81. $returnType .= $array ? '[]' : '';
  82. $this->assertEquals($returnType, $this->getReturnType($reflMethod));
  83. }
  84. }
  85. }
  86. }
  87. public function testModels()
  88. {
  89. foreach ($this->description['models'] as $resource => $models) {
  90. $resource = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $resource)));
  91. $namespace = '\\RestCord\\Model\\'.ucwords($resource).'\\';
  92. foreach ($models as $method => $data) {
  93. $class = $namespace.ucwords($method);
  94. $this->assertTrue(class_exists($class), 'Could not find interface: '.$class);
  95. $refl = new \ReflectionClass($class);
  96. foreach ($data['properties'] as $name => $info) {
  97. $name = lcfirst(str_replace([' ', '?'], '', str_replace('-', '_', $name)));
  98. $this->assertTrue($refl->hasProperty($name), "Cannot find property $name on $class");
  99. }
  100. }
  101. }
  102. }
  103. private function mapBadDocs($cls)
  104. {
  105. switch ($cls) {
  106. case '\RestCord\Model\User\DmChannel':
  107. $cls = '\RestCord\Model\Channel\DmChannel';
  108. break;
  109. case '\RestCord\Model\Channel\Invite':
  110. case '\RestCord\Model\Guild\Invite':
  111. $cls = '\RestCord\Model\Invite\Invite';
  112. break;
  113. case '\RestCord\Model\Guild\GuildChannel':
  114. $cls = '\RestCord\Model\Channel\GuildChannel';
  115. break;
  116. case '\RestCord\Model\Guild\User':
  117. case '\RestCord\Model\Channel\User':
  118. $cls = '\RestCord\Model\User\User';
  119. break;
  120. default:
  121. return $cls;
  122. }
  123. return $cls;
  124. }
  125. private function getReturnType(\ReflectionMethod $reflMethod)
  126. {
  127. $comment = $reflMethod->getDocComment();
  128. $regex = '/@return ([\\\\A-Za-z\[\]]+)/';
  129. preg_match($regex, $comment, $matches);
  130. if (empty($matches)) {
  131. return;
  132. }
  133. return $matches[1];
  134. }
  135. }