ComposerIntegrationTest.php 5.51 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace Drupal\Tests;

/**
 * Tests Composer integration.
 *
 * @group Composer
 */
class ComposerIntegrationTest extends UnitTestCase {

  /**
   * Gets human-readable JSON error messages.
   *
   * @return string[]
   *   Keys are JSON_ERROR_* constants.
   */
  protected function getErrorMessages() {
    $messages = [
20
      0 => 'No errors found',
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
      JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
      JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
      JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
      JSON_ERROR_SYNTAX => 'Syntax error',
      JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
    ];

    if (version_compare(phpversion(), '5.5.0', '>=')) {
      $messages[JSON_ERROR_RECURSION] = 'One or more recursive references in the value to be encoded';
      $messages[JSON_ERROR_INF_OR_NAN] = 'One or more NAN or INF values in the value to be encoded';
      $messages[JSON_ERROR_UNSUPPORTED_TYPE] = 'A value of a type that cannot be encoded was given';
    }

    return $messages;
  }

  /**
   * Gets the paths to the folders that contain the Composer integration.
   *
   * @return string[]
   *   The paths.
   */
  protected function getPaths() {
    return [
      $this->root,
      $this->root . '/core',
47
48
      $this->root . '/core/lib/Drupal/Component/Annotation',
      $this->root . '/core/lib/Drupal/Component/Assertion',
49
      $this->root . '/core/lib/Drupal/Component/Bridge',
50
      $this->root . '/core/lib/Drupal/Component/Datetime',
51
      $this->root . '/core/lib/Drupal/Component/DependencyInjection',
52
53
54
55
      $this->root . '/core/lib/Drupal/Component/Diff',
      $this->root . '/core/lib/Drupal/Component/Discovery',
      $this->root . '/core/lib/Drupal/Component/EventDispatcher',
      $this->root . '/core/lib/Drupal/Component/FileCache',
56
      $this->root . '/core/lib/Drupal/Component/FileSystem',
57
      $this->root . '/core/lib/Drupal/Component/Gettext',
58
59
60
      $this->root . '/core/lib/Drupal/Component/Graph',
      $this->root . '/core/lib/Drupal/Component/HttpFoundation',
      $this->root . '/core/lib/Drupal/Component/PhpStorage',
61
62
      $this->root . '/core/lib/Drupal/Component/Plugin',
      $this->root . '/core/lib/Drupal/Component/ProxyBuilder',
63
64
65
      $this->root . '/core/lib/Drupal/Component/Render',
      $this->root . '/core/lib/Drupal/Component/Serialization',
      $this->root . '/core/lib/Drupal/Component/Transliteration',
66
      $this->root . '/core/lib/Drupal/Component/Utility',
67
      $this->root . '/core/lib/Drupal/Component/Uuid',
68
69
70
71
72
73
74
75
76
77
    ];
  }

  /**
   * Tests composer.json.
   */
  public function testComposerJson() {
    foreach ($this->getPaths() as $path) {
      $json = file_get_contents($path . '/composer.json');
      $result = json_decode($json);
78
      $this->assertNotNull($result, $this->getErrorMessages()[json_last_error()]);
79
80
81
    }
  }

82
  /**
83
   * Tests composer.lock content-hash.
84
85
   */
  public function testComposerLockHash() {
86
    $content_hash = self::getContentHash(file_get_contents($this->root . '/composer.json'));
87
    $lock = json_decode(file_get_contents($this->root . '/composer.lock'), TRUE);
88
    $this->assertSame($content_hash, $lock['content-hash']);
89
90
  }

91
92
93
94
95
96
97
  /**
   * Tests core's composer.json replace section.
   *
   * Verify that all core modules are also listed in the 'replace' section of
   * core's composer.json.
   */
  public function testAllModulesReplaced() {
98
99
100
101
    // Assemble a path to core modules.
    $module_path = $this->root . '/core/modules';

    // Grab the 'replace' section of the core composer.json file.
102
    $json = json_decode(file_get_contents($this->root . '/core/composer.json'));
103
    $composer_replace_packages = (array) $json->replace;
104

105
106
    // Get a list of all the files in the module path.
    $folders = scandir($module_path);
107

108
    // Make sure we only deal with directories that aren't . or ..
109
    $module_names = [];
110
    $discard = ['.', '..'];
111
    foreach ($folders as $file_name) {
112
      if ((!in_array($file_name, $discard)) && is_dir($module_path . '/' . $file_name)) {
113
114
115
116
        $module_names[] = $file_name;
      }
    }

117
118
    // Assert that each core module has a corresponding 'replace' in
    // composer.json.
119
    foreach ($module_names as $module_name) {
120
121
122
123
124
      $this->assertArrayHasKey(
        'drupal/' . $module_name,
        $composer_replace_packages,
        'Unable to find ' . $module_name . ' in replace list of composer.json'
      );
125
126
127
    }
  }

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  // @codingStandardsIgnoreStart
  /**
   * The following method is copied from \Composer\Package\Locker.
   *
   * @see https://github.com/composer/composer
   */
  /**
   * Returns the md5 hash of the sorted content of the composer file.
   *
   * @param string $composerFileContents The contents of the composer file.
   *
   * @return string
   */
  protected static function getContentHash($composerFileContents)
  {
    $content = json_decode($composerFileContents, true);

    $relevantKeys = array(
      'name',
      'version',
      'require',
      'require-dev',
      'conflict',
      'replace',
      'provide',
      'minimum-stability',
      'prefer-stable',
      'repositories',
      'extra',
    );

    $relevantContent = array();

    foreach (array_intersect($relevantKeys, array_keys($content)) as $key) {
      $relevantContent[$key] = $content[$key];
    }
    if (isset($content['config']['platform'])) {
      $relevantContent['config']['platform'] = $content['config']['platform'];
    }

    ksort($relevantContent);

    return md5(json_encode($relevantContent));
  }
  // @codingStandardsIgnoreEnd

174
}