Force membership auto-renew on by default
[civicrm-core.git] / Civi / Test.php
1 <?php
2 namespace Civi;
3
4 use PDO;
5 use PDOException;
6
7 /**
8 * Class Test
9 *
10 * A facade for managing the test environment.
11 */
12 class Test {
13
14 /**
15 * @var array
16 */
17 private static $singletons = [];
18
19 /**
20 * Get the data source used for testing.
21 *
22 * @param string|NULL $part
23 * One of NULL, 'hostspec', 'port', 'username', 'password', 'database'.
24 * @return string|array|NULL
25 * If $part is omitted, return full DSN array.
26 * If $part is a string, return that part of the DSN.
27 */
28 public static function dsn($part = NULL) {
29 if (!isset(self::$singletons['dsn'])) {
30 require_once "DB.php";
31 self::$singletons['dsn'] = \DB::parseDSN(CIVICRM_DSN);
32 }
33
34 if ($part === NULL) {
35 return self::$singletons['dsn'];
36 }
37
38 if (isset(self::$singletons['dsn'][$part])) {
39 return self::$singletons['dsn'][$part];
40 }
41
42 return NULL;
43 }
44
45 /**
46 * Get a connection to the test database.
47 *
48 * @return \PDO
49 */
50 public static function pdo() {
51 if (!isset(self::$singletons['pdo'])) {
52 $dsninfo = self::dsn();
53 $host = $dsninfo['hostspec'];
54 $port = @$dsninfo['port'];
55 try {
56 self::$singletons['pdo'] = new PDO("mysql:host={$host}" . ($port ? ";port=$port" : ""),
57 $dsninfo['username'], $dsninfo['password'],
58 [PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE]
59 );
60 }
61 catch (PDOException $e) {
62 echo "Can't connect to MySQL server:" . PHP_EOL . $e->getMessage() . PHP_EOL;
63 exit(1);
64 }
65 }
66 return self::$singletons['pdo'];
67 }
68
69 /**
70 * Create a builder for the headless environment.
71 *
72 * @return \Civi\Test\CiviEnvBuilder
73 *
74 * @code
75 * \Civi\Test::headless()->apply();
76 * \Civi\Test::headless()->sqlFile('ex.sql')->apply();
77 * @endCode
78 */
79 public static function headless() {
80 $civiRoot = dirname(__DIR__);
81 $builder = new \Civi\Test\CiviEnvBuilder('CiviEnvBuilder');
82 $builder
83 ->callback(function ($ctx) {
84 if (CIVICRM_UF !== 'UnitTests') {
85 throw new \RuntimeException("\\Civi\\Test::headless() requires CIVICRM_UF=UnitTests");
86 }
87 $dbName = \Civi\Test::dsn('database');
88 echo "Installing {$dbName} schema\n";
89 \Civi\Test::schema()->dropAll();
90 }, 'headless-drop')
91 ->sqlFile($civiRoot . "/sql/civicrm.mysql")
92 ->sql("DELETE FROM civicrm_extension")
93 ->callback(function ($ctx) {
94 \Civi\Test::data()->populate();
95 }, 'populate');
96 return $builder;
97 }
98
99 /**
100 * Create a builder for end-to-end testing on the live environment.
101 *
102 * @return \Civi\Test\CiviEnvBuilder
103 *
104 * @code
105 * \Civi\Test::e2e()->apply();
106 * \Civi\Test::e2e()->install('foo.bar')->apply();
107 * @endCode
108 */
109 public static function e2e() {
110 $builder = new \Civi\Test\CiviEnvBuilder('CiviEnvBuilder');
111 $builder
112 ->callback(function ($ctx) {
113 if (CIVICRM_UF === 'UnitTests') {
114 throw new \RuntimeException("\\Civi\\Test::e2e() requires a real CMS. Found CIVICRM_UF=UnitTests.");
115 }
116 }, 'e2e-check');
117 return $builder;
118 }
119
120 /**
121 * @return \Civi\Test\Schema
122 */
123 public static function schema() {
124 if (!isset(self::$singletons['schema'])) {
125 self::$singletons['schema'] = new \Civi\Test\Schema();
126 }
127 return self::$singletons['schema'];
128 }
129
130 /**
131 * @return \Civi\Test\Data
132 */
133 public static function data() {
134 if (!isset(self::$singletons['data'])) {
135 self::$singletons['data'] = new \Civi\Test\Data('CiviTesterData');
136 }
137 return self::$singletons['data'];
138 }
139
140 /**
141 * Prepare and execute a batch of SQL statements.
142 *
143 * @param string $query
144 * @return bool
145 */
146 public static function execute($query) {
147 $pdo = \Civi\Test::pdo();
148
149 $string = preg_replace("/^#[^\n]*$/m", "\n", $query);
150 $string = preg_replace("/^(--[^-]).*/m", "\n", $string);
151
152 $queries = preg_split('/;\s*$/m', $string);
153 foreach ($queries as $query) {
154 $query = trim($query);
155 if (!empty($query)) {
156 $result = $pdo->query($query);
157 if ($pdo->errorCode() == 0) {
158 continue;
159 }
160 else {
161 var_dump($result);
162 var_dump($pdo->errorInfo());
163 // die( "Cannot execute $query: " . $pdo->errorInfo() );
164 }
165 }
166 }
167 return TRUE;
168 }
169
170 }