/tests/src/Testrunner.php

https://github.com/WhichBrowser/Parser · PHP · 244 lines · 192 code · 52 blank · 0 comment · 45 complexity · 02e92d21c19cd45e8b411757563177e8 MD5 · raw file

  1. <?php
  2. namespace WhichBrowser;
  3. use Symfony\Component\Yaml\Yaml;
  4. class Testrunner
  5. {
  6. public static function compare($files, $skipManufacturers = false)
  7. {
  8. @unlink('runner.log');
  9. $result = true;
  10. foreach ($files as $file) {
  11. if ($skipManufacturers && substr(basename($file), 0, 13) == 'manufacturer-') {
  12. continue;
  13. }
  14. $result = self::compareFile($file, $skipManufacturers) && $result;
  15. }
  16. return $result;
  17. }
  18. private static function compareFile($file)
  19. {
  20. $fp = fopen('runner.log', 'a+');
  21. $name = basename(dirname($file)) . DIRECTORY_SEPARATOR . basename($file);
  22. $success = 0;
  23. $failed = 0;
  24. $total = 0;
  25. $rebase = false;
  26. $found = false;
  27. if (file_exists($file)) {
  28. $found = true;
  29. $rules = Yaml::parse(file_get_contents($file));
  30. foreach ($rules as $rule) {
  31. $options = $rule;
  32. if (isset($options['headers']) && is_string($options['headers'])) {
  33. $options['headers'] = http_parse_headers($options['headers']);
  34. }
  35. if (isset($options['result'])) {
  36. unset($options['result']);
  37. }
  38. $detected = new Parser($options);
  39. if (isset($rule['result'])) {
  40. if ($detected->toArray() != $rule['result'] || $detected->toString() != $rule['readable']) {
  41. fwrite($fp, "\n{$name}\n--------------\n\n");
  42. if ($detected->toString() != $rule['readable']) {
  43. fwrite($fp, $rule['readable'] . "\n");
  44. fwrite($fp, $detected->toString() . "\n\n");
  45. } else {
  46. fwrite($fp, $detected->toString() . "\n\n");
  47. }
  48. if (isset($options['headers'])) {
  49. foreach ($options['headers'] as $k => $v) {
  50. fwrite($fp, $k . ': ' . $v . "\n");
  51. }
  52. }
  53. fwrite($fp, "\n");
  54. fwrite($fp, "Base:\n");
  55. fwrite($fp, Yaml::dump($rule['result']) . "\n");
  56. fwrite($fp, "Calculated:\n");
  57. fwrite($fp, Yaml::dump($detected->toArray()) . "\n");
  58. $failed++;
  59. } else {
  60. $success++;
  61. }
  62. } else {
  63. fwrite($fp, "\n{$name}\n--------------\n\n");
  64. fwrite($fp, $detected->toString() . "\n\n");
  65. if (isset($options['headers'])) {
  66. foreach ($options['headers'] as $k => $v) {
  67. fwrite($fp, $k . ': ' . $v . "\n");
  68. }
  69. }
  70. fwrite($fp, "\n");
  71. fwrite($fp, "New result:\n");
  72. try {
  73. fwrite($fp, Yaml::dump($detected->toArray()) . "\n");
  74. } catch (Exception $e) {
  75. echo $rule['headers'] . "\n";
  76. var_dump($detected);
  77. }
  78. $rebase = true;
  79. }
  80. $total++;
  81. }
  82. }
  83. fclose($fp);
  84. $counter = "[{$success}/{$total}]";
  85. echo $success == $total && $found ? "\033[0;32m" : "\033[0;31m";
  86. echo $counter;
  87. echo "\033[0m";
  88. echo str_repeat(' ', 16 - strlen($counter));
  89. echo $name;
  90. echo (!$found ? "\t\t\033[0;31m => file not found!\033[0m" : "");
  91. echo ($rebase ? "\t\t\033[0;31m => rebase required!\033[0m" : "");
  92. echo "\n";
  93. return $success == $total && !$rebase;
  94. }
  95. public static function search($files, $query = '')
  96. {
  97. foreach ($files as $file) {
  98. self::searchFile($file, $query);
  99. }
  100. }
  101. private static function searchFile($file, $query)
  102. {
  103. $rules = self::sortRules(Yaml::parse(file_get_contents($file)));
  104. foreach ($rules as $rule) {
  105. if (is_string($rule['headers'])) {
  106. $rule['headers'] = http_parse_headers($rule['headers']);
  107. }
  108. if (isset($rule['headers']['User-Agent'])) {
  109. echo $rule['headers']['User-Agent'] . "\n";
  110. }
  111. }
  112. }
  113. public static function rebase($files, $sort)
  114. {
  115. foreach ($files as $file) {
  116. self::rebaseFile($file, $sort);
  117. }
  118. }
  119. private static function rebaseFile($file, $sort)
  120. {
  121. $result = [];
  122. if (file_exists($file)) {
  123. $rules = Yaml::parse(file_get_contents($file));
  124. if (is_array($rules)) {
  125. echo "Rebasing {$file}\n";
  126. foreach ($rules as $k => $v) {
  127. if (is_string($rules[$k]['headers'])) {
  128. $rules[$k]['headers'] = http_parse_headers($rules[$k]['headers']);
  129. }
  130. }
  131. if ($sort) {
  132. $rules = self::sortRules($rules);
  133. }
  134. foreach ($rules as $rule) {
  135. if (count($rule['headers']) > 1) {
  136. $headers = $rule['headers'];
  137. } else {
  138. $key = array_keys($rule['headers'])[0];
  139. $headers = $key . ': ' . $rule['headers'][$key];
  140. }
  141. $options = $rule;
  142. if (isset($options['result'])) {
  143. unset($options['result']);
  144. }
  145. $detected = new Parser($options);
  146. $rule['headers'] = $headers;
  147. $rule['readable'] = $detected->toString();
  148. $rule['result'] = $detected->toArray();
  149. $result[] = $rule;
  150. }
  151. if (count($result)) {
  152. if (count($result) == count($rules)) {
  153. if ($string = Yaml::dump($result)) {
  154. file_put_contents($file . '.tmp', $string);
  155. rename($file, $file . '.old');
  156. rename($file . '.tmp', $file);
  157. unlink($file . '.old');
  158. }
  159. } else {
  160. echo "Rebasing {$file}\t\t\033[0;31m => output does not match input\033[0m\n";
  161. }
  162. } else {
  163. echo "Rebasing {$file}\t\t\033[0;31m => no results found\033[0m\n";
  164. }
  165. } else {
  166. echo "Rebasing {$file}\t\t\033[0;31m => error reading file\033[0m\n";
  167. }
  168. } else {
  169. echo "Rebasing {$file}\t\t\033[0;31m => file not found\033[0m\n";
  170. }
  171. }
  172. private static function sortRules($rules)
  173. {
  174. usort($rules, function ($a, $b) {
  175. $ah = $a['headers'];
  176. $bh = $b['headers'];
  177. $as = '';
  178. $bs = '';
  179. if (isset($ah['User-Agent'])) {
  180. $as = $ah['User-Agent'];
  181. }
  182. if (isset($bh['User-Agent'])) {
  183. $bs = $bh['User-Agent'];
  184. }
  185. if ($ah == $bh) {
  186. return 0;
  187. }
  188. return ($ah > $bh) ? +1 : -1;
  189. });
  190. return $rules;
  191. }
  192. }