~ubuntu-branches/ubuntu/wily/phabricator/wily

« back to all changes in this revision

Viewing changes to libphutil/src/__tests__/PhutilLibraryTestCase.php

  • Committer: Package Import Robot
  • Author(s): Richard Sellam
  • Date: 2015-01-29 00:15:58 UTC
  • mfrom: (0.14.1) (0.13.1) (0.10.2) (2.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20150129001558-7qklhtcc043y9mog
Tags: 0~git20150129-1
* New snapshot release
* restricted access to local config file (closes: #775479)
* moved local config file to /var/lib/phabricator (closes: #775478)
* switched mysql-server dependency to recommends (closes: #773536)
* use /run instead of /var/run (closes: #775803)
* prevent package reinstall from overwritting local changes (closes: #776288)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
/**
 
4
 * @concrete-extensible
 
5
 */
 
6
class PhutilLibraryTestCase extends PhutilTestCase {
 
7
 
 
8
  /**
 
9
   * This is more of an acceptance test case instead of a unit test. It verifies
 
10
   * that all symbols can be loaded correctly. It can catch problems like
 
11
   * missing methods in descendants of abstract base classes.
 
12
   */
 
13
  public function testEverythingImplemented() {
 
14
    id(new PhutilSymbolLoader())
 
15
      ->setLibrary($this->getLibraryName())
 
16
      ->selectAndLoadSymbols();
 
17
    $this->assertTrue(true);
 
18
  }
 
19
 
 
20
  /**
 
21
   * This is more of an acceptance test case instead of a unit test. It verifies
 
22
   * that all the library map is up-to-date.
 
23
   */
 
24
  public function testLibraryMap() {
 
25
    $root = $this->getLibraryRoot();
 
26
    $library = phutil_get_library_name_for_root($root);
 
27
 
 
28
    $new_library_map = id(new PhutilLibraryMapBuilder($root))
 
29
      ->buildMap();
 
30
 
 
31
    $bootloader = PhutilBootloader::getInstance();
 
32
    $old_library_map = $bootloader->getLibraryMapWithoutExtensions($library);
 
33
    unset($old_library_map[PhutilLibraryMapBuilder::LIBRARY_MAP_VERSION_KEY]);
 
34
 
 
35
    $this->assertEqual(
 
36
      $new_library_map,
 
37
      $old_library_map,
 
38
      pht(
 
39
        'The library map does not appear to be up-to-date. Try '.
 
40
        'rebuilding the map with `%s`.',
 
41
        'arc liberate'));
 
42
  }
 
43
 
 
44
  /**
 
45
   * This is more of an acceptance test case instead of a unit test. It verifies
 
46
   * that methods in subclasses have the same visibility as the method in the
 
47
   * parent class.
 
48
   */
 
49
  public function testMethodVisibility() {
 
50
    $symbols = id(new PhutilSymbolLoader())
 
51
      ->setLibrary($this->getLibraryName())
 
52
      ->selectSymbolsWithoutLoading();
 
53
 
 
54
    $classes = array();
 
55
    foreach ($symbols as $symbol) {
 
56
      if ($symbol['type'] == 'class') {
 
57
        $classes[$symbol['name']] = new ReflectionClass($symbol['name']);
 
58
      }
 
59
    }
 
60
 
 
61
    $failures = array();
 
62
 
 
63
    foreach ($classes as $class_name => $class) {
 
64
      $parents = array();
 
65
      $parent = $class;
 
66
      while ($parent = $parent->getParentClass()) {
 
67
        $parents[] = $parent;
 
68
      }
 
69
 
 
70
      $interfaces = $class->getInterfaces();
 
71
 
 
72
      foreach ($class->getMethods() as $method) {
 
73
        $visibility = $this->getVisibility($method);
 
74
        $method_name = $method->getName();
 
75
 
 
76
        foreach (array_merge($parents, $interfaces) as $extends) {
 
77
          if ($extends->hasMethod($method_name)) {
 
78
            $xmethod = $extends->getMethod($method_name);
 
79
            $xvisibility = $this->getVisibility($xmethod);
 
80
 
 
81
            if ($xvisibility != $visibility) {
 
82
              $failures[] = pht(
 
83
                'Class "%s" implements method "%s" with the wrong visibility. '.
 
84
                'The method has visibility "%s", but it is defined in parent '.
 
85
                '"%s" with visibility "%s". In Phabricator, a method which '.
 
86
                'overrides another must always have the same visibility.',
 
87
                $class_name,
 
88
                $method_name,
 
89
                $visibility,
 
90
                $extends->getName(),
 
91
                $xvisibility);
 
92
            }
 
93
 
 
94
            // We found a declaration somewhere, so stop looking.
 
95
            break;
 
96
          }
 
97
        }
 
98
      }
 
99
    }
 
100
 
 
101
    $this->assertTrue(
 
102
      empty($failures),
 
103
      "\n\n".implode("\n\n", $failures));
 
104
  }
 
105
 
 
106
  /**
 
107
   * Get the name of the library currently being tested.
 
108
   */
 
109
  protected function getLibraryName() {
 
110
    return phutil_get_library_name_for_root($this->getLibraryRoot());
 
111
  }
 
112
 
 
113
  /**
 
114
   * Get the root directory for the library currently being tested.
 
115
   */
 
116
  protected function getLibraryRoot() {
 
117
    $caller = id(new ReflectionClass($this))->getFileName();
 
118
    return phutil_get_library_root_for_path($caller);
 
119
  }
 
120
 
 
121
  private function getVisibility(ReflectionMethod $method) {
 
122
    if ($method->isPrivate()) {
 
123
      return 'private';
 
124
    } else if ($method->isProtected()) {
 
125
      return 'protected';
 
126
    } else {
 
127
      return 'public';
 
128
    }
 
129
  }
 
130
 
 
131
}