DatabaseTest.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <?php
  2. class Elgg_DatabaseTest extends PHPUnit_Framework_TestCase {
  3. private $dbClass, $configClass;
  4. /**
  5. * Inspect instances in DI container to get correct classnames for
  6. * Database API.
  7. */
  8. public function setUp() {
  9. // Database class
  10. // Cannot user _elgg_services() because ElggEntityTest replace
  11. // the database instance with a mock.
  12. $db = _elgg_create_service_provider()->db;
  13. $this->dbClass = get_class($db);
  14. // Config class
  15. $reflectionClass = new ReflectionClass($db);
  16. $reflectionProperty = $reflectionClass->getProperty('config');
  17. if (method_exists($reflectionProperty, 'setAccessible')) {
  18. $reflectionProperty->setAccessible(true);
  19. $config = $reflectionProperty->getValue($db);
  20. $this->configClass = get_class($config);
  21. } else {
  22. $this->configClass = 'Elgg_Database_Config';
  23. }
  24. }
  25. /**
  26. * @dataProvider scriptsWithOneStatement
  27. */
  28. public function test_runSqlScript_withOneStatement($script) {
  29. $db = $this->getDbMock();
  30. $db->expects($this->exactly(1))
  31. ->method('updateData')
  32. ->with($this->matchesRegularExpression("/^INSERT INTO test_sometable \(`key`\)\sVALUES \('Value(?: -- not a comment)?'\)$/"));
  33. $db->runSqlScript($this->getFixture($script));
  34. }
  35. public function scriptsWithOneStatement() {
  36. return array(
  37. array('one_statement.sql'),
  38. array('one_statement_multiline.sql'),
  39. array('one_statement_with_comments.sql'),
  40. );
  41. }
  42. /**
  43. * @dataProvider scriptsWithMultipleStatements
  44. * @todo Use @see withConsecutive() to test consecutive method calls after upgrading to PHPUnit 4.
  45. */
  46. public function test_runSqlScript_withMultipleStatements($script) {
  47. // Verify that exactly three statements are executed
  48. $db1 = $this->getDbMock();
  49. $db1->expects($this->exactly(3))->method('updateData');
  50. $db1->runSqlScript($this->getFixture($script));
  51. // Verify that executed statements matches fixtures
  52. $db2 = $this->getDbMock();
  53. $this->expectExecutedStatement($db2, 0, $this->matches("INSERT INTO test_sometable (`key`) VALUES ('Value 1')"));
  54. $this->expectExecutedStatement($db2, 1, $this->matchesRegularExpression("/^UPDATE test_sometable\s+SET `key` = 'Value 2'\s+WHERE `key` = 'Value 1'$/"));
  55. $this->expectExecutedStatement($db2, 2, $this->matches("INSERT INTO test_sometable (`key`) VALUES ('Value 3')"));
  56. $db2->runSqlScript($this->getFixture($script));
  57. }
  58. public function scriptsWithMultipleStatements() {
  59. return array(
  60. array('multiple_statements.sql'),
  61. array('multiple_statements_with_comments.sql'),
  62. );
  63. }
  64. public function testFingerprintingOfCallbacks() {
  65. $db = $this->getDbMock();
  66. $prints = array();
  67. $uniques = 0;
  68. $prints[$db->fingerprintCallback('foo')] = true;
  69. $uniques++;
  70. $prints[$db->fingerprintCallback('foo::bar')] = true;
  71. $prints[$db->fingerprintCallback(array('foo', 'bar'))] = true;
  72. $uniques++;
  73. $obj1 = new Elgg_DatabaseTestObj();
  74. $prints[$db->fingerprintCallback(array($obj1, '__invoke'))] = true;
  75. $prints[$db->fingerprintCallback($obj1)] = true;
  76. $uniques++;
  77. $obj2 = new Elgg_DatabaseTestObj();
  78. $prints[$db->fingerprintCallback(array($obj2, '__invoke'))] = true;
  79. $uniques++;
  80. $this->assertEquals($uniques, count($prints));
  81. }
  82. private function getFixture($filename) {
  83. return dirname(__FILE__) .
  84. DIRECTORY_SEPARATOR . '..' .
  85. DIRECTORY_SEPARATOR . 'test_files' .
  86. DIRECTORY_SEPARATOR . 'sql' .
  87. DIRECTORY_SEPARATOR . $filename;
  88. }
  89. /**
  90. * @return PHPUnit_Framework_MockObject_MockObject
  91. */
  92. private function getDbMock()
  93. {
  94. return $this->getMock(
  95. $this->dbClass,
  96. array('updateData'),
  97. array(
  98. new $this->configClass((object) array('dbprefix' => 'test_')),
  99. _elgg_services()->logger
  100. )
  101. );
  102. }
  103. /**
  104. * @param PHPUnit_Framework_MockObject_MockObject $db
  105. * @param int $index
  106. * @param PHPUnit_Framework_MockObject_Matcher $matcher
  107. */
  108. private function expectExecutedStatement($db, $index, $matcher)
  109. {
  110. $db->expects($this->at($index))->method('updateData')->with($matcher);
  111. }
  112. }
  113. class Elgg_DatabaseTestObj {
  114. public function __invoke() {}
  115. }