├── .gitignore ├── EnhanceTestFramework.php ├── README.md ├── parse.php ├── parseACL.php ├── parseCloud.php ├── parseFile.php ├── parseGeoPoint.php ├── parseObject.php ├── parsePush.php ├── parseQuery.php ├── parseUser.php ├── test.php └── tests ├── parseFileTest.php ├── parseGeoPointTest.php ├── parseObjectTest.php ├── parsePushTest.php ├── parseQueryTest.php └── parseUserTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | parseConfig.php 2 | -------------------------------------------------------------------------------- /EnhanceTestFramework.php: -------------------------------------------------------------------------------- 1 | discoverTests($path, $isRecursive, $excludeRules); 29 | } 30 | 31 | public static function runTests($output = TemplateType::Html) 32 | { 33 | self::setInstance(); 34 | self::$Instance->runTests($output); 35 | } 36 | 37 | public static function getCodeCoverageWrapper($className, $args = null) 38 | { 39 | self::setInstance(); 40 | self::$Instance->registerForCodeCoverage($className); 41 | return new CodeCoverageWrapper($className, $args); 42 | } 43 | 44 | public static function log($className, $methodName) 45 | { 46 | self::setInstance(); 47 | self::$Instance->log($className, $methodName); 48 | } 49 | 50 | public static function getScenario($className, $args = null) 51 | { 52 | return new Scenario($className, $args, self::$Language); 53 | } 54 | 55 | public static function setInstance() 56 | { 57 | if (self::$Instance === null) { 58 | self::$Instance = new EnhanceTestFramework(self::$Language); 59 | } 60 | } 61 | } 62 | 63 | // Public API 64 | class TestFixture 65 | { 66 | 67 | } 68 | 69 | // Public API 70 | class MockFactory 71 | { 72 | public static function createMock($typeName) 73 | { 74 | return new Mock($typeName, true, Core::getLanguage()); 75 | } 76 | } 77 | 78 | // Public API 79 | class StubFactory 80 | { 81 | public static function createStub($typeName) 82 | { 83 | return new Mock($typeName, false, Core::getLanguage()); 84 | } 85 | } 86 | 87 | // Public API 88 | class Expect 89 | { 90 | const AnyValue = 'ENHANCE_ANY_VALUE_WILL_DO'; 91 | 92 | public static function method($methodName) 93 | { 94 | $expectation = new Expectation(Core::getLanguage()); 95 | return $expectation->method($methodName); 96 | } 97 | 98 | public static function getProperty($propertyName) 99 | { 100 | $expectation = new Expectation(Core::getLanguage()); 101 | return $expectation->getProperty($propertyName); 102 | } 103 | 104 | public static function setProperty($propertyName) 105 | { 106 | $expectation = new Expectation(Core::getLanguage()); 107 | return $expectation->setProperty($propertyName); 108 | } 109 | } 110 | 111 | // Public API 112 | class Assert 113 | { 114 | /** @var Assertions $EnhanceAssertions */ 115 | private static $EnhanceAssertions; 116 | 117 | private static function GetEnhanceAssertionsInstance() 118 | { 119 | if(self::$EnhanceAssertions === null) { 120 | self::$EnhanceAssertions = new Assertions(Core::getLanguage()); 121 | } 122 | return self::$EnhanceAssertions; 123 | } 124 | 125 | public static function areIdentical($expected, $actual) 126 | { 127 | self::GetEnhanceAssertionsInstance()->areIdentical($expected, $actual); 128 | } 129 | 130 | public static function areNotIdentical($expected, $actual) 131 | { 132 | self::GetEnhanceAssertionsInstance()->areNotIdentical($expected, $actual); 133 | } 134 | 135 | public static function isTrue($actual) 136 | { 137 | self::GetEnhanceAssertionsInstance()->isTrue($actual); 138 | } 139 | 140 | public static function isFalse($actual) 141 | { 142 | self::GetEnhanceAssertionsInstance()->isFalse($actual); 143 | } 144 | 145 | public static function isNull($actual) 146 | { 147 | self::GetEnhanceAssertionsInstance()->isNull($actual); 148 | } 149 | 150 | public static function isNotNull($actual) 151 | { 152 | self::GetEnhanceAssertionsInstance()->isNotNull($actual); 153 | } 154 | 155 | public static function isArray($actual) 156 | { 157 | self::GetEnhanceAssertionsInstance()->isArray($actual); 158 | } 159 | 160 | public static function isNotArray($actual) 161 | { 162 | self::GetEnhanceAssertionsInstance()->isNotArray($actual); 163 | } 164 | 165 | public static function isBool($actual) 166 | { 167 | self::GetEnhanceAssertionsInstance()->isBool($actual); 168 | } 169 | 170 | public static function isNotBool($actual) 171 | { 172 | self::GetEnhanceAssertionsInstance()->isNotBool($actual); 173 | } 174 | 175 | public static function isFloat($actual) 176 | { 177 | self::GetEnhanceAssertionsInstance()->isFloat($actual); 178 | } 179 | 180 | public static function isNotFloat($actual) 181 | { 182 | self::GetEnhanceAssertionsInstance()->isNotFloat($actual); 183 | } 184 | 185 | public static function isInt($actual) 186 | { 187 | self::GetEnhanceAssertionsInstance()->isInt($actual); 188 | } 189 | 190 | public static function isNotInt($actual) 191 | { 192 | self::GetEnhanceAssertionsInstance()->isNotInt($actual); 193 | } 194 | 195 | public static function isNumeric($actual) 196 | { 197 | self::GetEnhanceAssertionsInstance()->isNumeric($actual); 198 | } 199 | 200 | public static function isNotNumeric($actual) 201 | { 202 | self::GetEnhanceAssertionsInstance()->isNotNumeric($actual); 203 | } 204 | 205 | public static function isObject($actual) 206 | { 207 | self::GetEnhanceAssertionsInstance()->isObject($actual); 208 | } 209 | 210 | public static function isNotObject($actual) 211 | { 212 | self::GetEnhanceAssertionsInstance()->isNotObject($actual); 213 | } 214 | 215 | public static function isResource($actual) 216 | { 217 | self::GetEnhanceAssertionsInstance()->isResource($actual); 218 | } 219 | 220 | public static function isNotResource($actual) 221 | { 222 | self::GetEnhanceAssertionsInstance()->isNotResource($actual); 223 | } 224 | 225 | public static function isScalar($actual) 226 | { 227 | self::GetEnhanceAssertionsInstance()->isScalar($actual); 228 | } 229 | 230 | public static function isNotScalar($actual) 231 | { 232 | self::GetEnhanceAssertionsInstance()->isNotScalar($actual); 233 | } 234 | 235 | public static function isString($actual) 236 | { 237 | self::GetEnhanceAssertionsInstance()->isString($actual); 238 | } 239 | 240 | public static function isNotString($actual) 241 | { 242 | self::GetEnhanceAssertionsInstance()->isNotString($actual); 243 | } 244 | 245 | public static function contains($expected, $actual) 246 | { 247 | self::GetEnhanceAssertionsInstance()->contains($expected, $actual); 248 | } 249 | 250 | public static function notContains($expected, $actual) 251 | { 252 | self::GetEnhanceAssertionsInstance()->notContains($expected, $actual); 253 | } 254 | 255 | public static function fail() 256 | { 257 | self::GetEnhanceAssertionsInstance()->fail(); 258 | } 259 | 260 | public static function inconclusive() 261 | { 262 | self::GetEnhanceAssertionsInstance()->inconclusive(); 263 | } 264 | 265 | public static function isInstanceOfType($expected, $actual) 266 | { 267 | self::GetEnhanceAssertionsInstance()->isInstanceOfType($expected, $actual); 268 | } 269 | 270 | public static function isNotInstanceOfType($expected, $actual) 271 | { 272 | self::GetEnhanceAssertionsInstance()->isNotInstanceOfType($expected, $actual); 273 | } 274 | 275 | public static function throws($class, $methodName, $args = null) 276 | { 277 | self::GetEnhanceAssertionsInstance()->throws($class, $methodName, $args); 278 | } 279 | } 280 | 281 | // Internal Workings 282 | // You don't need to call any of these bits directly - use the public API above, which will 283 | // use the stuff below to carry out your tests! 284 | 285 | class TextFactory 286 | { 287 | public static $Text; 288 | 289 | public static function getLanguageText($language) 290 | { 291 | if (self::$Text === null) { 292 | $languageClass = 'Enhance\Text' . $language; 293 | self::$Text = new $languageClass(); 294 | } 295 | return self::$Text; 296 | } 297 | } 298 | 299 | class TextEn 300 | { 301 | public $FormatForTestRunTook = 'Test run took {0} seconds'; 302 | public $FormatForExpectedButWas = 'Expected {0} but was {1}'; 303 | public $FormatForExpectedNotButWas = 'Expected NOT {0} but was {1}'; 304 | public $FormatForExpectedContainsButWas = 'Expected to contain {0} but was {1}'; 305 | public $FormatForExpectedNotContainsButWas = 'Expected NOT to contain {0} but was {1}'; 306 | public $EnhanceTestFramework = 'Enhance Test Framework'; 307 | public $EnhanceTestFrameworkFull = 'Enhance PHP Unit Testing Framework'; 308 | public $TestResults = 'Test Results'; 309 | public $Test = 'Test'; 310 | public $TestPassed = 'Test Passed'; 311 | public $TestFailed = 'Test Failed'; 312 | public $Passed = 'Passed'; 313 | public $Failed = 'Failed'; 314 | public $ExpectationFailed = 'Expectation failed'; 315 | public $Expected = 'Expected'; 316 | public $Called = 'Called'; 317 | public $InconclusiveOrNotImplemented = 'Inconclusive or not implemented'; 318 | public $Times = 'Times'; 319 | public $MethodCoverage = 'Method Coverage'; 320 | public $Copyright = 'Copyright'; 321 | public $ExpectedExceptionNotThrown = 'Expected exception was not thrown'; 322 | public $CannotCallVerifyOnStub = 'Cannot call VerifyExpectations on a stub'; 323 | public $ReturnsOrThrowsNotBoth = 'You must only set a single return value (1 returns() or 1 throws())'; 324 | public $ScenarioWithExpectMismatch = 'Scenario must be initialised with the same number of "with" and "expect" calls'; 325 | public $LineFile = 'Line {0} in file {1}'; 326 | } 327 | 328 | class TextDe 329 | { 330 | public $FormatForTestRunTook = 'Fertig nach {0} Sekunden'; 331 | public $FormatForExpectedButWas = 'Erwartet {0} aber war {1}'; 332 | public $FormatForExpectedNotButWas = 'Erwartet nicht {0} aber war {1}'; 333 | public $FormatForExpectedContainsButWas = 'Erwartet {0} zu enthalten, aber war {1}'; 334 | public $FormatForExpectedNotContainsButWas = 'Erwartet {0} nicht zu enthalten, aber war {1}'; 335 | public $EnhanceTestFramework = 'Enhance Test-Rahmen'; 336 | public $EnhanceTestFrameworkFull = 'Maßeinheits-Prüfungs-Rahmen'; 337 | public $TestResults = 'Testergebnisse'; 338 | public $Test = 'Test'; 339 | public $TestPassed = 'Test bestehen'; 340 | public $TestFailed = 'Test durchfallen'; 341 | public $Passed = 'Bestehen'; 342 | public $Failed = 'Durchfallen'; 343 | public $ExpectationFailed = 'Erwartung durchfallen'; 344 | public $Expected = 'Erwartet'; 345 | public $Called = 'Benannt'; 346 | public $InconclusiveOrNotImplemented = 'Unbestimmt oder nicht durchgefuert'; 347 | public $Times = 'Ereignisse'; 348 | public $MethodCoverage = 'Methodenbehandlung'; 349 | public $Copyright = 'Copyright'; 350 | public $ExpectedExceptionNotThrown = 'Die Ausnahme wird nicht ausgeloest'; 351 | public $CannotCallVerifyOnStub = 'Kann VerifyExpectations auf einem Stub nicht aufrufen'; 352 | public $ReturnsOrThrowsNotBoth = 'Sie müssen einen einzelnen Return Value nur einstellen'; 353 | public $ScenarioWithExpectMismatch = 'Szenarium muss mit der gleichen Zahl von "With" und "Expect" calls initialisiert werden'; 354 | public $LineFile = 'Zeile {0} der Datei {1}'; 355 | public $TypeOfVar=" Typ: "; 356 | } 357 | 358 | class TextPtBr 359 | { 360 | public $FormatForTestRunTook = 'Execução de teste levou {0} segundos'; 361 | public $FormatForExpectedButWas = 'Esperado {0} mas foi {1}'; 362 | public $FormatForExpectedNotButWas = 'Não era esperado {0} mas foi {1}'; 363 | public $FormatForExpectedContainsButWas = 'Era esperado ser {0} mas foi {1}'; 364 | public $FormatForExpectedNotContainsButWas = 'Não era esperado seer {0} mas foi {1}'; 365 | public $EnhanceTestFramework = 'Framework de teste Enhance'; 366 | public $EnhanceTestFrameworkFull = 'Framework de teste unitário com PHP Enhance'; 367 | public $TestResults = 'Resultado do teste'; 368 | public $Test = 'Teste'; 369 | public $TestPassed = 'Teste passou'; 370 | public $TestFailed = 'Teste falhou'; 371 | public $Passed = 'Passou'; 372 | public $Failed = 'Falhou'; 373 | public $ExpectationFailed = 'Probabilidade falhou'; 374 | public $Expected = 'Probabilidade'; 375 | public $Called = 'Chamado'; 376 | public $InconclusiveOrNotImplemented = 'Inconclusivo ou não implementado'; 377 | public $Times = 'Vezes'; 378 | public $MethodCoverage = 'Cobertura de método'; 379 | public $Copyright = 'Direitos autorais'; 380 | public $ExpectedExceptionNotThrown = 'Exceção esperada não ocorreu'; 381 | public $CannotCallVerifyOnStub = 'Não foi possível chamar um esboço de VerifyExpectations'; 382 | public $ReturnsOrThrowsNotBoth = 'Você só deve definer um único valor de retorno (1 retorno() ou 1 throw())'; 383 | public $ScenarioWithExpectMismatch = 'Cenário deve ser iniciado com o mesmo número de chamadas de "with" e "expect"'; 384 | public $LineFile = 'Linha {0} no arquivo {1}'; 385 | public $TypeOfVar=" Tipo: "; 386 | } 387 | 388 | class TextSp 389 | { 390 | public $FormatForTestRunTook = 'La ejecución de las pruebas tomó {0} segundos'; 391 | public $FormatForExpectedButWas = 'Se esperaba {0} pero se obuvo {1}'; 392 | public $FormatForExpectedNotButWas = 'Se esperada Negación {0} pero se obtuvo {1}'; 393 | public $FormatForExpectedContainsButWas = 'Se esperaba tuviera {0} pero se obtuvo {1}'; 394 | public $FormatForExpectedNotContainsButWas = 'Se esperaba NO tuviera {0} pero se obtuvo {1}'; 395 | public $EnhanceTestFramework = 'Enhance Test Framework'; 396 | public $EnhanceTestFrameworkFull = 'Enhance PHP Unit Herramienta de pruebas'; 397 | public $TestResults = 'Resultado de las pruebas'; 398 | public $Test = 'Prueba'; 399 | public $TestPassed = 'Prueba pasó'; 400 | public $TestFailed = 'Prueba Fallo'; 401 | public $Passed = 'Pasó'; 402 | public $Failed = 'Fallo'; 403 | public $ExpectationFailed = 'Fallo en valor esperado'; 404 | public $Expected = 'Esperado'; 405 | public $Called = 'Llamada'; 406 | public $InconclusiveOrNotImplemented = 'Inconcluso o no implementado'; 407 | public $Times = 'Veces'; 408 | public $MethodCoverage = 'Covertura de Métodos'; 409 | public $Copyright = 'Copyright'; 410 | public $ExpectedExceptionNotThrown = 'La excepción esperada no fue generada'; 411 | public $CannotCallVerifyOnStub = 'No se puede llamar VerifyExpectations en un stub'; 412 | public $ReturnsOrThrowsNotBoth = 'Debe proporcionar un solo valor de retorno (1 returns() ó 1 throws())'; 413 | public $ScenarioWithExpectMismatch = 'Escenario debe ser inicializado con el mismo número de llamadas "with" y "expect" '; 414 | public $LineFile = 'Linha {0} no arquivo {1}'; 415 | public $TypeOfVar=" Tipo: "; 416 | } 417 | 418 | class EnhanceTestFramework 419 | { 420 | private $FileSystem; 421 | private $Text; 422 | private $Tests = array(); 423 | private $Results = array(); 424 | private $Errors = array(); 425 | private $Duration; 426 | private $MethodCalls = array(); 427 | private $Language; 428 | 429 | public function __construct($language) 430 | { 431 | $this->Text = TextFactory::getLanguageText($language); 432 | $this->FileSystem = new FileSystem(); 433 | $this->Language = $language; 434 | } 435 | 436 | public function discoverTests($path, $isRecursive, $excludeRules) 437 | { 438 | $directory = rtrim($path, '/'); 439 | if (is_dir($directory)) { 440 | $phpFiles = $this->FileSystem->getFilesFromDirectory($directory, $isRecursive, $excludeRules); 441 | foreach ($phpFiles as $file) { 442 | /** @noinspection PhpIncludeInspection */ 443 | include_once($file); 444 | } 445 | } 446 | } 447 | 448 | public function runTests($output) 449 | { 450 | $this->getTestFixturesByParent(); 451 | $this->run(); 452 | 453 | if(PHP_SAPI === 'cli' && $output != TemplateType::Tap) { 454 | $output = TemplateType::Cli; 455 | } 456 | 457 | $OutputTemplate = TemplateFactory::createOutputTemplate($output, $this->Language); 458 | echo $OutputTemplate->get( 459 | $this->Errors, 460 | $this->Results, 461 | $this->Text, 462 | $this->Duration, 463 | $this->MethodCalls 464 | ); 465 | 466 | if (count($this->Errors) > 0) { 467 | exit(1); 468 | } else { 469 | exit(0); 470 | } 471 | } 472 | 473 | public function log($className, $methodName) 474 | { 475 | $index = $this->getMethodIndex($className, $methodName); 476 | if (array_key_exists($index ,$this->MethodCalls)) { 477 | $this->MethodCalls[$index] = $this->MethodCalls[$index] + 1; 478 | } 479 | } 480 | 481 | public function registerForCodeCoverage($className) 482 | { 483 | $classMethods = get_class_methods($className); 484 | foreach($classMethods as $methodName) { 485 | $index = $this->getMethodIndex($className, $methodName); 486 | if (!array_key_exists($index ,$this->MethodCalls)) { 487 | $this->MethodCalls[$index] = 0; 488 | } 489 | } 490 | } 491 | 492 | private function getMethodIndex($className, $methodName) 493 | { 494 | return $className . '#' . $methodName; 495 | } 496 | 497 | private function getTestFixturesByParent() 498 | { 499 | $classes = get_declared_classes(); 500 | foreach($classes as $className) { 501 | $this->AddClassIfTest($className); 502 | } 503 | } 504 | 505 | private function AddClassIfTest($className) 506 | { 507 | $parentClassName = get_parent_class($className); 508 | if ($parentClassName === 'Enhance\TestFixture') { 509 | $instance = new $className(); 510 | $this->addFixture($instance); 511 | } else { 512 | $ancestorClassName = get_parent_class($parentClassName); 513 | if ($ancestorClassName === 'Enhance\TestFixture') { 514 | $instance = new $className(); 515 | $this->addFixture($instance); 516 | } 517 | } 518 | } 519 | 520 | private function addFixture($class) 521 | { 522 | $classMethods = get_class_methods($class); 523 | foreach($classMethods as $method) { 524 | if (strtolower($method) !== 'setup' && strtolower($method) !== 'teardown') { 525 | $reflection = new \ReflectionMethod($class, $method); 526 | if ($reflection->isPublic()) { 527 | $this->addTest($class, $method); 528 | } 529 | } 530 | } 531 | } 532 | 533 | private function addTest($class, $method) 534 | { 535 | $testMethod = new Test($class, $method); 536 | $this->Tests[] = $testMethod; 537 | } 538 | 539 | private function run() 540 | { 541 | $start = microtime(true); 542 | foreach($this->Tests as /** @var Test $test */ $test) { 543 | $result = $test->run(); 544 | if ($result) { 545 | $message = $test->getTestName() . ' - ' . $this->Text->Passed; 546 | $this->Results[] = new TestMessage($message, $test, true); 547 | } else { 548 | $message = '['. str_replace('{0}', $test->getLine(), str_replace('{1}', $test->getFile(), $this->Text->LineFile)) . '] ' . 549 | $test->getTestName() . ' - ' . 550 | $this->Text->Failed . ' - ' . $test->getMessage(); 551 | $this->Errors[] = new TestMessage($message, $test, false); 552 | } 553 | } 554 | $this->Duration = microtime(true) - $start; 555 | } 556 | } 557 | 558 | class FileSystem 559 | { 560 | public function getFilesFromDirectory($directory, $isRecursive, $excludeRules) 561 | { 562 | $files = array(); 563 | if ($handle = opendir($directory)) { 564 | while (false !== ($file = readdir($handle))) { 565 | if ($file != '.' && $file != '..' && strpos($file, '.') !== 0) { 566 | if ($this->isFolderExcluded($file, $excludeRules)){ 567 | continue; 568 | } 569 | 570 | if(is_dir($directory . '/' . $file)) { 571 | if ($isRecursive) { 572 | $dir2 = $directory . '/' . $file; 573 | $files[] = $this->getFilesFromDirectory($dir2, $isRecursive, $excludeRules); 574 | } 575 | } else { 576 | $files[] = $directory . '/' . $file; 577 | } 578 | } 579 | } 580 | closedir($handle); 581 | } 582 | return $this->flattenArray($files); 583 | } 584 | 585 | private function isFolderExcluded($folder, $excludeRules) 586 | { 587 | $folder = substr($folder, strrpos($folder, '/')); 588 | 589 | foreach ($excludeRules as $excluded){ 590 | if ($folder === $excluded){ 591 | return true; 592 | } 593 | } 594 | return false; 595 | } 596 | 597 | public function flattenArray($array) 598 | { 599 | $merged = array(); 600 | foreach($array as $a) { 601 | if(is_array($a)) { 602 | $merged = array_merge($merged, $this->flattenArray($a)); 603 | } else { 604 | $merged[] = $a; 605 | } 606 | } 607 | return $merged; 608 | } 609 | } 610 | 611 | class TestMessage 612 | { 613 | public $Message; 614 | public $Test; 615 | public $IsPass; 616 | 617 | public function __construct($message, $test, $isPass) 618 | { 619 | $this->Message = $message; 620 | $this->Test = $test; 621 | $this->IsPass = $isPass; 622 | } 623 | } 624 | 625 | class Test 626 | { 627 | private $ClassName; 628 | private $TestName; 629 | private $TestMethod; 630 | private $SetUpMethod; 631 | private $TearDownMethod; 632 | private $Message; 633 | private $Line; 634 | private $File; 635 | 636 | public function __construct($class, $method) 637 | { 638 | $className = get_class($class); 639 | $this->ClassName = $className; 640 | $this->TestMethod = array($className, $method); 641 | $this->SetUpMethod = array($className, 'setUp'); 642 | $this->TearDownMethod = array($className, 'tearDown'); 643 | $this->TestName = $method; 644 | } 645 | 646 | public function getTestName() 647 | { 648 | return $this->TestName; 649 | } 650 | 651 | public function getClassName() 652 | { 653 | return $this->ClassName; 654 | } 655 | 656 | public function getMessage() 657 | { 658 | return $this->Message; 659 | } 660 | 661 | public function getLine() 662 | { 663 | return $this->Line; 664 | } 665 | 666 | public function getFile() 667 | { 668 | return $this->File; 669 | } 670 | 671 | public function run() 672 | { 673 | /** @var $testClass iTestable */ 674 | $testClass = new $this->ClassName(); 675 | 676 | try { 677 | if (is_callable($this->SetUpMethod)) { 678 | $testClass->setUp(); 679 | } 680 | } catch (\Exception $e) { } 681 | 682 | try { 683 | $testClass->{$this->TestName}(); 684 | $result = true; 685 | } catch (TestException $e) { 686 | $this->Message = $e->getMessage(); 687 | $this->Line = $e->getLine(); 688 | $this->File = pathinfo($e->getFile(), PATHINFO_BASENAME); 689 | $result = false; 690 | } 691 | 692 | try { 693 | if (is_callable($this->TearDownMethod)) { 694 | $testClass->tearDown(); 695 | } 696 | } catch (\Exception $e) { } 697 | 698 | return $result; 699 | } 700 | } 701 | 702 | class CodeCoverageWrapper 703 | { 704 | private $Instance; 705 | private $ClassName; 706 | 707 | public function __construct($className, $args) 708 | { 709 | $this->ClassName = $className; 710 | if ($args !== null) { 711 | $rc = new \ReflectionClass($className); 712 | $this->Instance = $rc->newInstanceArgs($args); 713 | } else { 714 | $this->Instance = new $className(); 715 | } 716 | Core::log($this->ClassName, $className); 717 | Core::log($this->ClassName, '__construct'); 718 | } 719 | 720 | public function __call($methodName, $args = null) 721 | { 722 | Core::log($this->ClassName, $methodName); 723 | if ($args !== null) { 724 | /** @noinspection PhpParamsInspection */ 725 | return call_user_func_array(array($this->Instance, $methodName), $args); 726 | } else { 727 | return $this->Instance->{$methodName}(); 728 | } 729 | } 730 | 731 | public function __get($propertyName) 732 | { 733 | return $this->Instance->{$propertyName}; 734 | } 735 | 736 | public function __set($propertyName, $value) 737 | { 738 | $this->Instance->{$propertyName} = $value; 739 | } 740 | } 741 | 742 | class Mock 743 | { 744 | private $IsMock; 745 | private $Text; 746 | private $ClassName; 747 | private $Expectations = array(); 748 | 749 | public function __construct($className, $isMock, $language) 750 | { 751 | $this->IsMock = $isMock; 752 | $this->ClassName = $className; 753 | $this->Text = TextFactory::getLanguageText($language); 754 | } 755 | 756 | public function addExpectation($expectation) 757 | { 758 | $this->Expectations[] = $expectation; 759 | } 760 | 761 | public function verifyExpectations() 762 | { 763 | if (!$this->IsMock) { 764 | throw new \Exception( 765 | $this->ClassName . ': ' . $this->Text->CannotCallVerifyOnStub 766 | ); 767 | } 768 | 769 | foreach ($this->Expectations as /** @var Expectation $expectation */ $expectation) { 770 | if (!$expectation->verify()) { 771 | $Arguments = ''; 772 | if (isset($expectation->MethodArguments)) { 773 | foreach($expectation->MethodArguments as $argument) { 774 | if (isset($Arguments[0])) { 775 | $Arguments .= ', '; 776 | } 777 | $Arguments .= $argument; 778 | } 779 | } 780 | 781 | throw new \Exception( 782 | $this->Text->ExpectationFailed . ' ' . 783 | $this->ClassName . '->' . $expectation->MethodName . '(' . $Arguments . ') ' . 784 | $this->Text->Expected . ' #' . $expectation->ExpectedCalls . ' ' . 785 | $this->Text->Called . ' #' . $expectation->ActualCalls, 0); 786 | } 787 | } 788 | } 789 | 790 | public function __call($methodName, $args) 791 | { 792 | return $this->getReturnValue('method', $methodName, $args); 793 | } 794 | 795 | public function __get($propertyName) 796 | { 797 | return $this->getReturnValue('getProperty', $propertyName, array()); 798 | } 799 | 800 | public function __set($propertyName, $value) 801 | { 802 | $this->getReturnValue('setProperty', $propertyName, array($value)); 803 | } 804 | 805 | private function getReturnValue($type, $methodName, $args) 806 | { 807 | $Expectation = $this->getMatchingExpectation($type, $methodName, $args); 808 | $Expected = true; 809 | if ($Expectation === null) { 810 | $Expected = false; 811 | } 812 | 813 | if ($Expected) { 814 | ++$Expectation->ActualCalls; 815 | if ($Expectation->ReturnException) { 816 | throw new \Exception($Expectation->ReturnValue); 817 | } 818 | return $Expectation->ReturnValue; 819 | } 820 | 821 | if ($this->IsMock) { 822 | throw new \Exception( 823 | $this->Text->ExpectationFailed . ' ' . 824 | $this->ClassName . '->' . $methodName . '(' . $args . ') ' . 825 | $this->Text->Expected . ' #0 ' . 826 | $this->Text->Called . ' #1', 0); 827 | } 828 | return null; 829 | } 830 | 831 | private function getMatchingExpectation($type, $methodName, $arguments) 832 | { 833 | foreach ($this->Expectations as $expectation) { 834 | if ($expectation->Type === $type) { 835 | if ($expectation->MethodName === $methodName) { 836 | $isMatch = true; 837 | if ($expectation->ExpectArguments) { 838 | $isMatch = $this->argumentsMatch( 839 | $expectation->MethodArguments, 840 | $arguments 841 | ); 842 | } 843 | if ($isMatch) { 844 | return $expectation; 845 | } 846 | } 847 | } 848 | } 849 | return null; 850 | } 851 | 852 | private function argumentsMatch($arguments1, $arguments2) 853 | { 854 | $Count1 = count($arguments1); 855 | $Count2 = count($arguments2); 856 | $isMatch = true; 857 | if ($Count1 === $Count2) { 858 | for ($i = 0; $i < $Count1; ++$i) { 859 | if ($arguments1[$i] === Expect::AnyValue 860 | || $arguments2[$i] === Expect::AnyValue) { 861 | // No need to match 862 | } else { 863 | if ($arguments1[$i] !== $arguments2[$i]) { 864 | $isMatch = false; 865 | } 866 | } 867 | } 868 | } else { 869 | $isMatch = false; 870 | } 871 | return $isMatch; 872 | } 873 | } 874 | 875 | class Scenario 876 | { 877 | private $Text; 878 | private $Class; 879 | private $FunctionName; 880 | private $Inputs = array(); 881 | private $Expectations = array(); 882 | 883 | public function __construct($class, $functionName, $language) 884 | { 885 | $this->Class = $class; 886 | $this->FunctionName = $functionName; 887 | $this->Text = TextFactory::getLanguageText($language); 888 | } 889 | 890 | public function with() 891 | { 892 | $this->Inputs[] = func_get_args(); 893 | return $this; 894 | } 895 | 896 | public function expect() 897 | { 898 | $this->Expectations[] = func_get_args(); 899 | return $this; 900 | } 901 | 902 | public function verifyExpectations() 903 | { 904 | if (count($this->Inputs) !== count($this->Expectations)) { 905 | throw new \Exception($this->Text->ScenarioWithExpectMismatch); 906 | } 907 | 908 | $exceptionText = ''; 909 | 910 | while(count($this->Inputs) > 0) { 911 | $input = array_shift($this->Inputs); 912 | $expected = array_shift($this->Expectations); 913 | $expected = $expected[0]; 914 | 915 | $actual = call_user_func_array(array($this->Class, $this->FunctionName), $input); 916 | 917 | if (is_float($expected)) { 918 | if ((string)$expected !== (string)$actual) { 919 | $exceptionText .= str_replace('{0}', $expected, str_replace('{1}', $actual, $this->Text->FormatForExpectedButWas)); 920 | } 921 | } elseif ($expected != $actual) { 922 | $exceptionText .= str_replace('{0}', $expected, str_replace('{1}', $actual, $this->Text->FormatForExpectedButWas)); 923 | } 924 | } 925 | 926 | if ($exceptionText !== ''){ 927 | throw new \Exception($exceptionText, 0); 928 | } 929 | } 930 | } 931 | 932 | class Expectation 933 | { 934 | public $MethodName; 935 | public $MethodArguments; 936 | public $ReturnValue; 937 | public $ReturnException; 938 | public $ExpectedCalls; 939 | public $ActualCalls; 940 | public $ExpectArguments; 941 | public $ExpectTimes; 942 | public $Type; 943 | public $Text; 944 | 945 | public function __construct($language) 946 | { 947 | $this->ExpectedCalls = -1; 948 | $this->ActualCalls = 0; 949 | $this->ExpectArguments = false; 950 | $this->ExpectTimes = false; 951 | $this->ReturnException = false; 952 | $this->ReturnValue = null; 953 | $textFactory = new TextFactory(); 954 | $this->Text = $textFactory->getLanguageText($language); 955 | } 956 | 957 | public function method($methodName) 958 | { 959 | $this->Type = 'method'; 960 | $this->MethodName = $methodName; 961 | return $this; 962 | } 963 | 964 | public function getProperty($propertyName) 965 | { 966 | $this->Type = 'getProperty'; 967 | $this->MethodName = $propertyName; 968 | return $this; 969 | } 970 | 971 | public function setProperty($propertyName) 972 | { 973 | $this->Type = 'setProperty'; 974 | $this->MethodName = $propertyName; 975 | return $this; 976 | } 977 | 978 | public function with() 979 | { 980 | $this->ExpectArguments = true; 981 | $this->MethodArguments = func_get_args(); 982 | return $this; 983 | } 984 | 985 | public function returns($returnValue) 986 | { 987 | if ($this->ReturnValue !== null) { 988 | throw new \Exception($this->Text->ReturnsOrThrowsNotBoth); 989 | } 990 | $this->ReturnValue = $returnValue; 991 | return $this; 992 | } 993 | 994 | public function throws($errorMessage) 995 | { 996 | if ($this->ReturnValue !== null) { 997 | throw new \Exception($this->Text->ReturnsOrThrowsNotBoth); 998 | } 999 | $this->ReturnValue = $errorMessage; 1000 | $this->ReturnException = true; 1001 | return $this; 1002 | } 1003 | 1004 | public function times($expectedCalls) 1005 | { 1006 | $this->ExpectTimes = true; 1007 | $this->ExpectedCalls = $expectedCalls; 1008 | return $this; 1009 | } 1010 | 1011 | public function verify() 1012 | { 1013 | $ExpectationMet = true; 1014 | if ($this->ExpectTimes) { 1015 | if ($this->ExpectedCalls !== $this->ActualCalls) { 1016 | $ExpectationMet = false; 1017 | } 1018 | } 1019 | return $ExpectationMet; 1020 | } 1021 | } 1022 | 1023 | class Assertions 1024 | { 1025 | private $Text; 1026 | 1027 | public function __construct($language) 1028 | { 1029 | $this->Text = TextFactory::getLanguageText($language); 1030 | } 1031 | 1032 | public function areIdentical($expected, $actual) 1033 | { 1034 | if (is_float($expected)) { 1035 | if ((string)$expected !== (string)$actual) { 1036 | throw new TestException( 1037 | str_replace('{0}', $this->getDescription($expected), 1038 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1039 | } 1040 | } elseif ($expected !== $actual) { 1041 | throw new TestException( 1042 | str_replace('{0}', $this->getDescription($expected), 1043 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1044 | } 1045 | } 1046 | 1047 | public function areNotIdentical($expected, $actual) 1048 | { 1049 | if (is_float($expected)) { 1050 | if ((string)$expected === (string)$actual) { 1051 | throw new TestException( 1052 | str_replace('{0}', $this->getDescription($expected), 1053 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1054 | } 1055 | } elseif ($expected === $actual) { 1056 | throw new TestException( 1057 | str_replace('{0}', $this->getDescription($expected), 1058 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1059 | } 1060 | } 1061 | 1062 | public function isTrue($actual) 1063 | { 1064 | if ($actual !== true) { 1065 | throw new TestException( 1066 | str_replace('{0}', 'true', 1067 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1068 | } 1069 | } 1070 | 1071 | public function isFalse($actual) 1072 | { 1073 | if ($actual !== false) { 1074 | throw new TestException( 1075 | str_replace('{0}', 'false', 1076 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1077 | } 1078 | } 1079 | 1080 | public function contains($expected, $actual) 1081 | { 1082 | $result = strpos($actual, $expected); 1083 | if ($result === false) { 1084 | throw new TestException( 1085 | str_replace('{0}', $this->getDescription($expected), 1086 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedContainsButWas)), 0); 1087 | } 1088 | } 1089 | 1090 | public function notContains($expected, $actual) 1091 | { 1092 | $result = strpos($actual, $expected); 1093 | if ($result !== false) { 1094 | throw new TestException( 1095 | str_replace('{0}', $this->getDescription($expected), 1096 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotContainsButWas)), 0); 1097 | } 1098 | } 1099 | 1100 | public function isNull($actual) 1101 | { 1102 | if ($actual !== null) { 1103 | throw new TestException( 1104 | str_replace('{0}', 'null', 1105 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1106 | } 1107 | } 1108 | 1109 | public function isNotNull($actual) 1110 | { 1111 | if ($actual === null) { 1112 | throw new TestException( 1113 | str_replace('{0}', 'null', 1114 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1115 | } 1116 | } 1117 | 1118 | public function isArray($actual) 1119 | { 1120 | if (!is_array($actual)) { 1121 | throw new TestException( 1122 | str_replace('{0}', 'null', 1123 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1124 | } 1125 | } 1126 | 1127 | public function isNotArray($actual) 1128 | { 1129 | if (is_array($actual)) { 1130 | throw new TestException( 1131 | str_replace('{0}', 'null', 1132 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1133 | } 1134 | } 1135 | 1136 | public function isBool($actual) 1137 | { 1138 | if (!is_bool($actual)) { 1139 | throw new TestException( 1140 | str_replace('{0}', 'null', 1141 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1142 | } 1143 | } 1144 | 1145 | public function isNotBool($actual) 1146 | { 1147 | if (is_bool($actual)) { 1148 | throw new TestException( 1149 | str_replace('{0}', 'null', 1150 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1151 | } 1152 | } 1153 | 1154 | public function isFloat($actual) 1155 | { 1156 | if (!is_float($actual)) { 1157 | throw new TestException( 1158 | str_replace('{0}', 'null', 1159 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1160 | } 1161 | } 1162 | 1163 | public function isNotFloat($actual) 1164 | { 1165 | if (is_float($actual)) { 1166 | throw new TestException( 1167 | str_replace('{0}', 'null', 1168 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1169 | } 1170 | } 1171 | 1172 | public function isInt($actual) 1173 | { 1174 | if (!is_int($actual)) { 1175 | throw new TestException( 1176 | str_replace('{0}', 'null', 1177 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1178 | } 1179 | } 1180 | 1181 | public function isNotInt($actual) 1182 | { 1183 | if (is_int($actual)) { 1184 | throw new TestException( 1185 | str_replace('{0}', 'null', 1186 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1187 | } 1188 | } 1189 | 1190 | public function isNumeric($actual) 1191 | { 1192 | if (!is_numeric($actual)) { 1193 | throw new TestException( 1194 | str_replace('{0}', 'null', 1195 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1196 | } 1197 | } 1198 | 1199 | public function isNotNumeric($actual) 1200 | { 1201 | if (is_numeric($actual)) { 1202 | throw new TestException( 1203 | str_replace('{0}', 'null', 1204 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1205 | } 1206 | } 1207 | 1208 | public function isObject($actual) 1209 | { 1210 | if (!is_object($actual)) { 1211 | throw new TestException( 1212 | str_replace('{0}', 'null', 1213 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1214 | } 1215 | } 1216 | 1217 | public function isNotObject($actual) 1218 | { 1219 | if (is_object($actual)) { 1220 | throw new TestException( 1221 | str_replace('{0}', 'null', 1222 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1223 | } 1224 | } 1225 | 1226 | public function isResource($actual) 1227 | { 1228 | if (!is_resource($actual)) { 1229 | throw new TestException( 1230 | str_replace('{0}', 'null', 1231 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1232 | } 1233 | } 1234 | 1235 | public function isNotResource($actual) 1236 | { 1237 | if (is_resource($actual)) { 1238 | throw new TestException( 1239 | str_replace('{0}', 'null', 1240 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1241 | } 1242 | } 1243 | 1244 | public function isScalar($actual) 1245 | { 1246 | if (!is_scalar($actual)) { 1247 | throw new TestException( 1248 | str_replace('{0}', 'null', 1249 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1250 | } 1251 | } 1252 | 1253 | public function isNotScalar($actual) 1254 | { 1255 | if (is_scalar($actual)) { 1256 | throw new TestException( 1257 | str_replace('{0}', 'null', 1258 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1259 | } 1260 | } 1261 | 1262 | public function isString($actual) 1263 | { 1264 | if (!is_string($actual)) { 1265 | throw new TestException( 1266 | str_replace('{0}', 'null', 1267 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedButWas)), 0); 1268 | } 1269 | } 1270 | 1271 | public function isNotString($actual) 1272 | { 1273 | if (is_string($actual)) { 1274 | throw new TestException( 1275 | str_replace('{0}', 'null', 1276 | str_replace('{1}', $this->getDescription($actual), $this->Text->FormatForExpectedNotButWas)), 0); 1277 | } 1278 | } 1279 | 1280 | public function fail() 1281 | { 1282 | throw new TestException($this->Text->Failed, 0); 1283 | } 1284 | 1285 | public function inconclusive() 1286 | { 1287 | throw new TestException($this->Text->InconclusiveOrNotImplemented, 0); 1288 | } 1289 | 1290 | public function isInstanceOfType($expected, $actual) 1291 | { 1292 | $actualType = get_class($actual); 1293 | if ($expected !== $actualType) { 1294 | throw new TestException( 1295 | str_replace('{0}', $expected, 1296 | str_replace('{1}', $actualType, $this->Text->FormatForExpectedButWas)), 0); 1297 | }; 1298 | } 1299 | 1300 | public function isNotInstanceOfType($expected, $actual) 1301 | { 1302 | $actualType = get_class($actual); 1303 | if ($expected === $actualType) { 1304 | throw new TestException( 1305 | str_replace('{0}', $expected, 1306 | str_replace('{1}', $actualType, $this->Text->FormatForExpectedNotButWas)), 0); 1307 | }; 1308 | } 1309 | 1310 | public function throws($class, $methodName, $args = null) 1311 | { 1312 | $exception = false; 1313 | 1314 | try { 1315 | if ($args !== null) { 1316 | /** @noinspection PhpParamsInspection */ 1317 | call_user_func_array(array($class, $methodName), $args); 1318 | } else { 1319 | $class->{$methodName}(); 1320 | } 1321 | } catch (\Exception $e) { 1322 | $exception = true; 1323 | } 1324 | 1325 | if (!$exception) { 1326 | throw new TestException($this->Text->ExpectedExceptionNotThrown, 0); 1327 | } 1328 | } 1329 | 1330 | private function getDescription($mixed) 1331 | { 1332 | if (is_object($mixed)){ 1333 | return get_class($mixed); 1334 | } else if (is_bool($mixed)){ 1335 | return $mixed ? 'true' : 'false'; 1336 | } else { 1337 | return (string) $mixed; 1338 | } 1339 | } 1340 | } 1341 | 1342 | class TestException extends \Exception 1343 | { 1344 | public function __construct($message = null, $code = 0, \Exception $previous = null) 1345 | { 1346 | parent::__construct($message, $code, $previous); 1347 | 1348 | $trace = $this->getTrace(); 1349 | 1350 | $this->line = $trace[1]['line']; 1351 | $this->file = $trace[1]['file']; 1352 | } 1353 | } 1354 | 1355 | interface iOutputTemplate 1356 | { 1357 | public function getTemplateType(); 1358 | public function get($errors, $results, $text, $duration, $methodCalls); 1359 | } 1360 | 1361 | interface iTestable 1362 | { 1363 | public function setUp(); 1364 | public function tearDown(); 1365 | } 1366 | 1367 | class HtmlTemplate implements iOutputTemplate 1368 | { 1369 | private $Text; 1370 | 1371 | public function __construct($language) 1372 | { 1373 | $this->Text = TextFactory::getLanguageText($language); 1374 | } 1375 | 1376 | public function getTemplateType() 1377 | { 1378 | return TemplateType::Html; 1379 | } 1380 | 1381 | public function get($errors, $results, $text, $duration, $methodCalls) 1382 | { 1383 | $message = ''; 1384 | $failCount = count($errors); 1385 | $passCount = count($results); 1386 | $methodCallCount = count($methodCalls); 1387 | 1388 | $currentClass = ''; 1389 | if ($failCount > 0) { 1390 | $message .= '

' . $text->Test . ' ' . $text->Failed . '

'; 1391 | 1392 | $message .= '
  • '; 1400 | } 1401 | $message .= '' . $testClassName . '
  • '; 1407 | } else { 1408 | $message .= '

    ' . $text->TestPassed . '

    '; 1409 | } 1410 | 1411 | $currentClass = ''; 1412 | if ($passCount > 0) { 1413 | $message .= '
  • '; 1421 | } 1422 | $message .= '' . $testClassName . '
  • '; 1428 | } 1429 | 1430 | $message .= '

    ' . $text->MethodCoverage . '

    '; 1431 | if ($methodCallCount > 0) { 1432 | $message .= ''; 1444 | } 1445 | 1446 | $message .= '

    ' . str_replace('{0}', $duration, $text->FormatForTestRunTook) . '

    '; 1447 | 1448 | return $this->getTemplateWithMessage($message); 1449 | } 1450 | 1451 | private function getTemplateWithMessage($content) 1452 | { 1453 | return str_replace('{0}', $content, ' 1454 | 1455 | 1456 | 1457 | ' . $this->Text->TestResults . ' 1458 | 1459 | 1460 | 1461 | 1480 | 1481 | 1482 |
    1483 |

    ' . $this->Text->EnhanceTestFramework . '

    1484 |
    1485 | 1486 |
    1487 | {0} 1488 |
    1489 | 1490 | 1495 | 1496 | '); 1497 | } 1498 | } 1499 | 1500 | class XmlTemplate implements iOutputTemplate 1501 | { 1502 | private $Text; 1503 | private $Tab = " "; 1504 | private $CR = "\n"; 1505 | 1506 | public function __construct($language) 1507 | { 1508 | $this->Text = TextFactory::getLanguageText($language); 1509 | } 1510 | 1511 | public function getTemplateType() 1512 | { 1513 | return TemplateType::Xml; 1514 | } 1515 | 1516 | public function get($errors, $results, $text, $duration, $methodCalls) 1517 | { 1518 | $message = ''; 1519 | $failCount = count($errors); 1520 | 1521 | $message .= '' . $this->CR; 1522 | if ($failCount > 0) { 1523 | $message .= $this->getNode(1, 'result', $text->TestFailed); 1524 | } else { 1525 | $message .= $this->getNode(1, 'result', $text->TestPassed); 1526 | } 1527 | 1528 | $message .= $this->Tab . '' . $this->CR . 1529 | $this->getBadResults($errors) . 1530 | $this->getGoodResults($results) . 1531 | $this->Tab . '' . $this->CR . 1532 | $this->Tab . '' . $this->CR . 1533 | $this->getCodeCoverage($methodCalls) . 1534 | $this->Tab . '' . $this->CR; 1535 | 1536 | $message .= $this->getNode(1, 'testRunDuration', $duration) . 1537 | '' . $this->CR; 1538 | 1539 | return $this->getTemplateWithMessage($message); 1540 | } 1541 | 1542 | public function getBadResults($errors) 1543 | { 1544 | $message = ''; 1545 | foreach ($errors as $error) { 1546 | $message .= $this->getNode(2, 'fail', $error->Message); 1547 | } 1548 | return $message; 1549 | } 1550 | 1551 | public function getGoodResults($results) 1552 | { 1553 | $message = ''; 1554 | foreach ($results as $result) { 1555 | $message .= $this->getNode(2, 'pass', $result->Message); 1556 | } 1557 | return $message; 1558 | } 1559 | 1560 | public function getCodeCoverage($methodCalls) 1561 | { 1562 | $message = ''; 1563 | foreach ($methodCalls as $key => $value) { 1564 | $message .= $this->buildCodeCoverageMessage($key, $value); 1565 | } 1566 | return $message; 1567 | } 1568 | 1569 | private function buildCodeCoverageMessage($key, $value) 1570 | { 1571 | return $this->Tab . $this->Tab . '' . $this->CR . 1572 | $this->getNode(3, 'name', str_replace('#', '->', $key)) . 1573 | $this->getNode(3, 'timesCalled', $value) . 1574 | $this->Tab . $this->Tab . '' . $this->CR; 1575 | } 1576 | 1577 | private function getNode($tabs, $nodeName, $nodeValue) 1578 | { 1579 | $node = ''; 1580 | for ($i = 0; $i < $tabs; ++$i){ 1581 | $node .= $this->Tab; 1582 | } 1583 | $node .= '<' . $nodeName . '>' . $nodeValue . '' . $this->CR; 1584 | 1585 | return $node; 1586 | } 1587 | 1588 | private function getTemplateWithMessage($content) 1589 | { 1590 | return str_replace('{0}', $content, '' . "\n" . 1591 | '{0}'); 1592 | } 1593 | } 1594 | 1595 | class CliTemplate implements iOutputTemplate 1596 | { 1597 | private $Text; 1598 | private $CR = "\n"; 1599 | 1600 | public function __construct($language) 1601 | { 1602 | $this->Text = TextFactory::getLanguageText($language); 1603 | } 1604 | 1605 | public function getTemplateType() 1606 | { 1607 | return TemplateType::Cli; 1608 | } 1609 | 1610 | public function get($errors, $results, $text, $duration, $methodCalls) 1611 | { 1612 | $failCount = count($errors); 1613 | 1614 | $resultMessage = $text->TestPassed . $this->CR; 1615 | if ($failCount > 0) { 1616 | $resultMessage = $text->TestFailed . $this->CR; 1617 | } 1618 | 1619 | $message = $this->CR . 1620 | $resultMessage . 1621 | $this->CR . 1622 | $this->getBadResults($errors) . 1623 | $this->getGoodResults($results) . 1624 | $this->CR . 1625 | $this->getMethodCoverage($methodCalls) . 1626 | $this->CR . 1627 | $resultMessage . 1628 | str_replace('{0}', $duration, $text->FormatForTestRunTook) . $this->CR; 1629 | 1630 | return $message; 1631 | } 1632 | 1633 | public function getBadResults($errors) 1634 | { 1635 | $message = ''; 1636 | foreach ($errors as $error) { 1637 | $message .= $error->Message . $this->CR; 1638 | } 1639 | return $message; 1640 | } 1641 | 1642 | public function getGoodResults($results) 1643 | { 1644 | $message = ''; 1645 | foreach ($results as $result) { 1646 | $message .= $result->Message . $this->CR; 1647 | } 1648 | return $message; 1649 | } 1650 | 1651 | public function getMethodCoverage($methodCalls) 1652 | { 1653 | $message = ''; 1654 | foreach ($methodCalls as $key => $value) { 1655 | $message .= str_replace('#', '->', $key) . ':' . $value . $this->CR; 1656 | } 1657 | return $message; 1658 | } 1659 | } 1660 | 1661 | class TapTemplate implements iOutputTemplate 1662 | { 1663 | private $Text; 1664 | private $CR = "\n"; 1665 | 1666 | public function __construct($language) 1667 | { 1668 | $this->Text = TextFactory::getLanguageText($language); 1669 | } 1670 | 1671 | public function getTemplateType() 1672 | { 1673 | return TemplateType::Cli; 1674 | } 1675 | 1676 | public function get($errors, $results, $text, $duration, $methodCalls) 1677 | { 1678 | $failCount = count($errors); 1679 | $passCount = count($results); 1680 | $total = $failCount + $passCount; 1681 | $count = 0; 1682 | 1683 | $message = '1..' . $total . $this->CR; 1684 | 1685 | foreach ($errors as $error) { 1686 | ++$count; 1687 | $message .= 'not ok ' . $count . ' ' . $error->Message . $this->CR; 1688 | } 1689 | 1690 | foreach ($results as $result) { 1691 | ++$count; 1692 | $message .= 'ok ' . $count . ' ' . $result->Message . $this->CR; 1693 | } 1694 | 1695 | return $message; 1696 | } 1697 | 1698 | } 1699 | 1700 | class TemplateFactory 1701 | { 1702 | public static function createOutputTemplate($type, $language) 1703 | { 1704 | switch ($type) { 1705 | case TemplateType::Xml: 1706 | return new XmlTemplate($language); 1707 | break; 1708 | case TemplateType::Html: 1709 | return new HtmlTemplate($language); 1710 | break; 1711 | case TemplateType::Cli: 1712 | return new CliTemplate($language); 1713 | break; 1714 | case TemplateType::Tap: 1715 | return new TapTemplate($language); 1716 | break; 1717 | } 1718 | 1719 | return new HtmlTemplate($language); 1720 | } 1721 | } 1722 | 1723 | class TemplateType 1724 | { 1725 | const Xml = 0; 1726 | const Html = 1; 1727 | const Cli = 2; 1728 | const Tap = 3; 1729 | } 1730 | 1731 | class Language 1732 | { 1733 | const English = 'En'; 1734 | const Deutsch = 'De'; 1735 | const BrazilianPortuguese = 'PtBr'; 1736 | const Spanish = 'Sp'; 1737 | } 1738 | 1739 | class Localisation 1740 | { 1741 | public $Language = Language::English; 1742 | } 1743 | ?> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHP parse.com API library 2 | =========================== 3 | More on the parse.com api here: https://www.parse.com/docs/rest 4 | 5 | ### V1 is still available ### 6 | Availalbe here: https://github.com/apotropaic/parse.com-php-library/blob/parse.com-php-library_v1/README.md 7 | 8 | I wrote tests not for testing sake, but really just to see how I liked how the library worked! 9 | 10 | ### Feedback Wanted ### 11 | 12 | This is a work in progress and is a drasticly different then v1 of this library. 13 | 14 | Let me know what you think and suggestions and ideas 15 | 16 | 17 | SETUP 18 | ========================= 19 | 20 | **Instructions** after cloning this repository you have to create a file in the root of it called **parseConfig.php** 21 | 22 | ### sample of parseConfig.php ### 23 | 24 | Below is what you want parseConfig.php to look like, just fill in your IDs and KEYs to get started. 25 | 26 | ``` 27 | 38 | 39 | ``` 40 | 41 | 42 | 43 | EXAMPLE 44 | ========================= 45 | 46 | ### sample of upload.php ### 47 | 48 | ``` 49 | title = $data['upload_data']['title']; 54 | $parse->description = $data['upload_data']['description']; 55 | $parse->tags = $data['upload_data']['tags']; 56 | 57 | //create new geo 58 | $geo = new parseGeoPoint($data['upload_data']['lat'],$data['upload_data']['lng']); 59 | $parse->location = $geo->location; 60 | 61 | //use pointer to other class 62 | $parse->userid = array("__type" => "Pointer", "className" => "_User", "objectId" => $data['upload_data']['userid']); 63 | 64 | //create acl 65 | $parse->ACL = array("*" => array("write" => true, "read" => true)); 66 | $r = $parse->save(); 67 | ?> 68 | ``` 69 | -------------------------------------------------------------------------------- /parse.php: -------------------------------------------------------------------------------- 1 | _appid = $parseConfig::APPID; 26 | $this->_masterkey = $parseConfig::MASTERKEY; 27 | $this->_restkey = $parseConfig::RESTKEY; 28 | $this->_parseurl = $parseConfig::PARSEURL; 29 | 30 | if(empty($this->_appid) || empty($this->_restkey) || empty($this->_masterkey)){ 31 | $this->throwError('You must set your Application ID, Master Key and REST API Key'); 32 | } 33 | 34 | $version = curl_version(); 35 | $ssl_supported = ( $version['features'] & CURL_VERSION_SSL ); 36 | 37 | if(!$ssl_supported){ 38 | $this->throwError('CURL ssl support not found'); 39 | } 40 | 41 | } 42 | 43 | /* 44 | * All requests go through this function 45 | * 46 | * 47 | */ 48 | public function request($args){ 49 | $isFile = false; 50 | $c = curl_init(); 51 | curl_setopt($c, CURLOPT_TIMEOUT, 30); 52 | curl_setopt($c, CURLOPT_USERAGENT, 'parse.com-php-library/2.0'); 53 | curl_setopt($c, CURLOPT_RETURNTRANSFER, true); 54 | curl_setopt($c, CURLINFO_HEADER_OUT, true); 55 | if(substr($args['requestUrl'],0,5) == 'files'){ 56 | curl_setopt($c, CURLOPT_HTTPHEADER, array( 57 | 'Content-Type: '.$args['contentType'], 58 | 'X-Parse-Application-Id: '.$this->_appid, 59 | 'X-Parse-Master-Key: '.$this->_masterkey 60 | )); 61 | $isFile = true; 62 | } 63 | else if(substr($args['requestUrl'],0,5) == 'users' && isset($args['sessionToken'])){ 64 | curl_setopt($c, CURLOPT_HTTPHEADER, array( 65 | 'Content-Type: application/json', 66 | 'X-Parse-Application-Id: '.$this->_appid, 67 | 'X-Parse-REST-API-Key: '.$this->_restkey, 68 | 'X-Parse-Session-Token: '.$args['sessionToken'] 69 | )); 70 | } 71 | else{ 72 | curl_setopt($c, CURLOPT_HTTPHEADER, array( 73 | 'Content-Type: application/json', 74 | 'X-Parse-Application-Id: '.$this->_appid, 75 | 'X-Parse-REST-API-Key: '.$this->_restkey, 76 | 'X-Parse-Master-Key: '.$this->_masterkey 77 | )); 78 | } 79 | curl_setopt($c, CURLOPT_CUSTOMREQUEST, $args['method']); 80 | $url = $this->_parseurl . $args['requestUrl']; 81 | 82 | if($args['method'] == 'PUT' || $args['method'] == 'POST'){ 83 | if($isFile){ 84 | $postData = $args['data']; 85 | } 86 | else{ 87 | $postData = json_encode($args['data']); 88 | } 89 | 90 | curl_setopt($c, CURLOPT_POSTFIELDS, $postData ); 91 | } 92 | 93 | if($args['requestUrl'] == 'login'){ 94 | $urlParams = http_build_query($args['data'], '', '&'); 95 | $url = $url.'?'.$urlParams; 96 | } 97 | if(array_key_exists('urlParams',$args)){ 98 | $urlParams = http_build_query($args['urlParams'], '', '&'); 99 | $url = $url.'?'.$urlParams; 100 | } 101 | 102 | curl_setopt($c, CURLOPT_URL, $url); 103 | 104 | $response = curl_exec($c); 105 | $responseCode = curl_getinfo($c, CURLINFO_HTTP_CODE); 106 | 107 | $expectedCode = array('200'); 108 | if($args['method'] == 'POST' && substr($args['requestUrl'],0,4) != 'push'){ 109 | // checking if it is not cloud code - it returns code 200 110 | if(substr($args['requestUrl'],0,9) != 'functions'){ 111 | $expectedCode = array('200','201'); 112 | } 113 | } 114 | 115 | //BELOW HELPS WITH DEBUGGING 116 | /* 117 | if(!in_array($responseCode,$expectedCode)){ 118 | //print_r($response); 119 | //print_r($args); 120 | } 121 | */ 122 | return $this->checkResponse($response,$responseCode,$expectedCode); 123 | } 124 | 125 | public function dataType($type,$params){ 126 | if($type != ''){ 127 | switch($type){ 128 | case 'date': 129 | $return = array( 130 | "__type" => "Date", 131 | "iso" => date("c", strtotime($params)) 132 | ); 133 | break; 134 | case 'bytes': 135 | $return = array( 136 | "__type" => "Bytes", 137 | "base64" => base64_encode($params) 138 | ); 139 | break; 140 | case 'pointer': 141 | $return = array( 142 | "__type" => "Pointer", 143 | "className" => $params[0], 144 | "objectId" => $params[1] 145 | ); 146 | break; 147 | case 'geopoint': 148 | $return = array( 149 | "__type" => "GeoPoint", 150 | "latitude" => floatval($params[0]), 151 | "longitude" => floatval($params[1]) 152 | ); 153 | break; 154 | case 'file': 155 | $return = array( 156 | "__type" => "File", 157 | "name" => $params[0], 158 | ); 159 | break; 160 | case 'increment': 161 | $return = array( 162 | "__op" => "Increment", 163 | "amount" => $params[0] 164 | ); 165 | break; 166 | case 'decrement': 167 | $return = array( 168 | "__op" => "Decrement", 169 | "amount" => $params[0] 170 | ); 171 | break; 172 | default: 173 | $return = false; 174 | break; 175 | } 176 | 177 | return $return; 178 | } 179 | } 180 | 181 | public function throwError($msg,$code=0){ 182 | throw new ParseLibraryException($msg,$code); 183 | } 184 | 185 | private function checkResponse($response,$responseCode,$expectedCode){ 186 | //TODO: Need to also check for response for a correct result from parse.com 187 | if(!in_array($responseCode,$expectedCode)){ 188 | $error = json_decode($response); 189 | $this->throwError($error->error,$error->code); 190 | } 191 | else{ 192 | //check for empty return 193 | if($response == '{}'){ 194 | return true; 195 | } 196 | else{ 197 | return json_decode($response); 198 | } 199 | } 200 | } 201 | } 202 | 203 | 204 | class ParseLibraryException extends Exception{ 205 | public function __construct($message, $code = 0, Exception $previous = null) { 206 | //codes are only set by a parse.com error 207 | if($code != 0){ 208 | $message = "parse.com error: ".$message; 209 | } 210 | 211 | parent::__construct($message, $code, $previous); 212 | } 213 | 214 | public function __toString() { 215 | return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; 216 | } 217 | 218 | } 219 | 220 | ?> -------------------------------------------------------------------------------- /parseACL.php: -------------------------------------------------------------------------------- 1 | __set('hello','world'); 6 | 7 | // This instantiates a ACL object with NO rights! 8 | $acl = new parseACL(); 9 | $acl->setPublicReadAccess(false); 10 | $acl->setReadAccessForId('user_id',true); 11 | $acl->setWriteAccessForRole('role_name',true); 12 | 13 | $object->ACL($acl); 14 | $object->save(); 15 | */ 16 | class parseACL{ 17 | public $acl; 18 | public function __construct(){ 19 | $this->acl = new stdClass(); 20 | } 21 | private function setAccessForKey($access,$key,$bool){ 22 | if(!($access == 'read' || $access == 'write')) return; 23 | if(is_object($this->acl)) $this->acl = array(); 24 | if($bool) $this->acl[$key][$access] = true; 25 | else { 26 | if(isset($this->acl[$key])){ 27 | unset($this->acl[$key][$access]); 28 | if(sizeof($this->acl[$key]) == 0) unset($this->acl[$key]); 29 | } 30 | if(sizeof($this->acl) == 0) $this->acl = new stdClass(); 31 | } 32 | } 33 | public function setPublicReadAccess($bool){ 34 | $this->setAccessForKey('read','*',$bool); 35 | } 36 | public function setPublicWriteAccess($bool){ 37 | $this->setAccessForKey('write','*',$bool); 38 | } 39 | public function setReadAccessForId($userId,$bool){ 40 | $this->setAccessForKey('read',$userId,$bool); 41 | } 42 | public function setWriteAccessForId($userId,$bool){ 43 | $this->setAccessForKey('write',$userId,$bool); 44 | } 45 | public function setReadAccessForRole($role,$bool){ 46 | $this->setAccessForKey('read','role:'.$role,$bool); 47 | } 48 | public function setWriteAccessForRole($role,$bool){ 49 | $this->setAccessForKey('write','role:'.$role,$bool); 50 | } 51 | } 52 | ?> -------------------------------------------------------------------------------- /parseCloud.php: -------------------------------------------------------------------------------- 1 | __set('action',1234); 7 | $cloud->__set('identifier',"aZ02fe2a"); 8 | // Running the cloud function 9 | $result = $cloud->run(); 10 | print_r($result); 11 | */ 12 | class parseCloud extends parseRestClient{ 13 | public $_options; 14 | private $_functionName = ''; 15 | 16 | public function __construct($function=''){ 17 | $this->_options = array(); 18 | if($function != ''){ 19 | $this->_functionName = $function; 20 | } 21 | else{ 22 | $this->throwError('include the functionName when creating a parseCloud'); 23 | } 24 | 25 | parent::__construct(); 26 | } 27 | 28 | public function __set($name,$value){ 29 | $this->_options[$name] = $value; 30 | } 31 | public function run(){ 32 | if($this->_functionName != ''){ 33 | $request = $this->request(array( 34 | 'method' => 'POST', 35 | 'requestUrl' => 'functions/'.$this->_functionName, 36 | 'data' => $this->_options, 37 | )); 38 | return $request; 39 | } 40 | } 41 | } 42 | 43 | ?> -------------------------------------------------------------------------------- /parseFile.php: -------------------------------------------------------------------------------- 1 | _contentType = $contentType; 11 | $this->data = $data; 12 | } 13 | 14 | parent::__construct(); 15 | 16 | } 17 | 18 | public function save($fileName){ 19 | if($fileName != '' && $this->_contentType != '' && $this->data != ''){ 20 | $request = $this->request(array( 21 | 'method' => 'POST', 22 | 'requestUrl' => 'files/'.$fileName, 23 | 'contentType' => $this->_contentType, 24 | 'data' => $this->data, 25 | )); 26 | return $request; 27 | } 28 | else{ 29 | $this->throwError('Please make sure you are passing a proper filename as string (e.g. hello.txt)'); 30 | } 31 | } 32 | 33 | public function delete($parseFileName){ 34 | if($parseFileName != ''){ 35 | $request = $this->request(array( 36 | 'method' => 'DELETE', 37 | 'requestUrl' => 'files/'.$parseFileName, 38 | 'contentType' => $this->_contentType, 39 | )); 40 | return $request; 41 | 42 | } 43 | } 44 | 45 | 46 | 47 | } 48 | 49 | ?> -------------------------------------------------------------------------------- /parseGeoPoint.php: -------------------------------------------------------------------------------- 1 | lat = $lat; 11 | $this->long = $long; 12 | $this->location = $this->dataType('geopoint', array($this->lat, $this->long)); 13 | } 14 | 15 | public function __toString(){ 16 | return json_encode($this->location); 17 | 18 | } 19 | 20 | public function get(){ 21 | return json_encode($this->location); 22 | 23 | } 24 | 25 | } 26 | 27 | ?> 28 | -------------------------------------------------------------------------------- /parseObject.php: -------------------------------------------------------------------------------- 1 | _className = $class; 10 | } 11 | else{ 12 | $this->throwError('include the className when creating a parseObject'); 13 | } 14 | 15 | parent::__construct(); 16 | } 17 | 18 | public function __set($name,$value){ 19 | if($name != '_className'){ 20 | $this->data[$name] = $value; 21 | } 22 | } 23 | 24 | public function save(){ 25 | if(count($this->data) > 0 && $this->_className != ''){ 26 | $request = $this->request(array( 27 | 'method' => 'POST', 28 | 'requestUrl' => 'classes/'.$this->_className, 29 | 'data' => $this->data, 30 | )); 31 | return $request; 32 | } 33 | } 34 | 35 | public function get($id){ 36 | if($this->_className != '' || !empty($id)){ 37 | $request = $this->request(array( 38 | 'method' => 'GET', 39 | 'requestUrl' => 'classes/'.$this->_className.'/'.$id 40 | )); 41 | 42 | if(!empty($this->_includes)){ 43 | $request['include'] = implode(',', $this->_includes); 44 | } 45 | 46 | return $request; 47 | } 48 | } 49 | 50 | public function update($id){ 51 | if($this->_className != '' || !empty($id)){ 52 | $request = $this->request(array( 53 | 'method' => 'PUT', 54 | 'requestUrl' => 'classes/'.$this->_className.'/'.$id, 55 | 'data' => $this->data, 56 | )); 57 | 58 | return $request; 59 | } 60 | } 61 | 62 | public function increment($field,$amount){ 63 | $this->data[$field] = $this->dataType('increment', $amount); 64 | } 65 | 66 | public function decrement($id){ 67 | $this->data[$field] = $this->dataType('decrement', $amount); 68 | } 69 | 70 | 71 | public function delete($id){ 72 | if($this->_className != '' || !empty($id)){ 73 | $request = $this->request(array( 74 | 'method' => 'DELETE', 75 | 'requestUrl' => 'classes/'.$this->_className.'/'.$id 76 | )); 77 | 78 | return $request; 79 | } 80 | } 81 | 82 | public function addInclude($name){ 83 | $this->_includes[] = $name; 84 | } 85 | } 86 | 87 | ?> -------------------------------------------------------------------------------- /parsePush.php: -------------------------------------------------------------------------------- 1 | _globalMsg = $globalMsg; 19 | } 20 | 21 | parent::__construct(); 22 | 23 | } 24 | 25 | public function __set($name,$value){ 26 | if($name != 'channel' || $name != 'channels' || $name != 'expiration_time' || $name != 'expiration_interval' || $name != 'type' || $name != 'data' || $name != 'where'){ 27 | $this->data[$name] = $value; 28 | } 29 | } 30 | 31 | public function send(){ 32 | if($this->_globalMsg != ''){ 33 | $request = $this->request(array( 34 | 'method' => 'POST', 35 | 'requestUrl' => 'push', 36 | 'data' => array( 37 | 'channel' => '', 38 | 'data' => array( 39 | 'alert' => $this->_globalMsg 40 | ) 41 | ), 42 | )); 43 | return $request; 44 | 45 | } 46 | else{ 47 | if(count($this->data) > 0){ 48 | if($this->channel == '' && empty($this->channels) && empty($this->where)){ 49 | $this->throwError('A push Channel must be set when not using Advanced Targeting'); 50 | } 51 | $params = array( 52 | 'method' => 'POST', 53 | 'requestUrl' => 'push', 54 | 'data' => array( 55 | 'data' => $this->data 56 | ) 57 | ); 58 | 59 | if(!empty($this->channels)){ 60 | $params['data']['channels'] = $this->channels; 61 | } 62 | if(!empty($this->channel)){ 63 | $params['data']['channel'] = $this->channel; 64 | } 65 | if(!empty($this->expiration_time)){ 66 | $params['data']['expiration_time'] = $this->expiration_time; 67 | } 68 | if(!empty($this->expiration_time_interval)){ 69 | $params['data']['expiration_interval'] = $this->expiration_interval; 70 | } 71 | if(!empty($this->content_available)){ 72 | //changed back to content-available... underscores are much easier to deal with in PHP 73 | $params['data']['content-available'] = $this->content_available; 74 | } 75 | if(!empty($this->type)){ 76 | $params['data']['type'] = $this->type; 77 | } 78 | if(!empty($this->where)){ 79 | $params['data']['where'] = $this->where; 80 | } 81 | 82 | $request = $this->request($params); 83 | return $request; 84 | 85 | } 86 | else{ 87 | $this->throwError('No push data has been set, you must set at least data. Please see the docs. '); 88 | } 89 | } 90 | } 91 | } 92 | 93 | ?> -------------------------------------------------------------------------------- /parseQuery.php: -------------------------------------------------------------------------------- 1 | _requestUrl = $class; 14 | } 15 | elseif($class != ''){ 16 | $this->_requestUrl = 'classes/'.$class; 17 | } 18 | else{ 19 | $this->throwError('include the className when creating a parseQuery'); 20 | } 21 | 22 | parent::__construct(); 23 | 24 | } 25 | 26 | public function find(){ 27 | if(empty($this->_query)){ 28 | $request = $this->request(array( 29 | 'method' => 'GET', 30 | 'requestUrl' => $this->_requestUrl 31 | )); 32 | 33 | return $request; 34 | 35 | } 36 | else{ 37 | $urlParams = array( 38 | 'where' => json_encode( $this->_query ) 39 | ); 40 | if(!empty($this->_include)){ 41 | $urlParams['include'] = implode(',',$this->_include); 42 | } 43 | if(!empty($this->_order)){ 44 | $urlParams['order'] = implode(',',$this->_order); 45 | } 46 | if(!empty($this->_limit) || $this->_limit == 0){ 47 | $urlParams['limit'] = $this->_limit; 48 | } 49 | if(!empty($this->_skip)){ 50 | $urlParams['skip'] = $this->_skip; 51 | } 52 | if($this->_count == 1){ 53 | $urlParams['count'] = '1'; 54 | } 55 | 56 | $request = $this->request(array( 57 | 'method' => 'GET', 58 | 'requestUrl' => $this->_requestUrl, 59 | 'urlParams' => $urlParams, 60 | )); 61 | 62 | return $request; 63 | } 64 | } 65 | //setting this to 1 by default since you'd typically only call this function if you were wanting to turn it on 66 | public function setCount($bool=1){ 67 | if(is_bool($bool)){ 68 | $this->_count = $bool; 69 | } 70 | else{ 71 | $this->throwError('setCount requires a boolean paremeter'); 72 | } 73 | } 74 | 75 | public function getCount(){ 76 | $this->_count = 1; 77 | $this->_limit = 0; 78 | return $this->find(); 79 | } 80 | 81 | public function setLimit($int){ 82 | if ($int >= 1 && $int <= 1000){ 83 | $this->_limit = $int; 84 | } 85 | else{ 86 | $this->throwError('parse requires the limit parameter be between 1 and 1000'); 87 | } 88 | } 89 | 90 | public function setSkip($int){ 91 | $this->_skip = $int; 92 | } 93 | 94 | public function orderBy($field){ 95 | if(!empty($field)){ 96 | $this->_order[] = $field; 97 | } 98 | } 99 | 100 | public function orderByAscending($value){ 101 | if(is_string($value)){ 102 | $this->_order[] = $value; 103 | } 104 | else{ 105 | $this->throwError('the order parameter on a query must be a string'); 106 | } 107 | } 108 | 109 | public function orderByDescending($value){ 110 | if(is_string($value)){ 111 | $this->_order[] = '-'.$value; 112 | } 113 | else{ 114 | $this->throwError('the order parameter on parseQuery must be a string'); 115 | } 116 | } 117 | 118 | public function whereInclude($value){ 119 | if(is_string($value)){ 120 | $this->_include[] = $value; 121 | } 122 | else{ 123 | $this->throwError('the include parameter on parseQuery must be a string'); 124 | } 125 | } 126 | 127 | public function where($key,$value){ 128 | $this->whereEqualTo($key,$value); 129 | } 130 | 131 | public function whereEqualTo($key,$value){ 132 | if(isset($key) && isset($value)){ 133 | $this->_query[$key] = $value; 134 | } 135 | else{ 136 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 137 | } 138 | } 139 | 140 | public function whereNotEqualTo($key,$value){ 141 | if(isset($key) && isset($value)){ 142 | $this->_query[$key] = array( 143 | '$ne' => $value 144 | ); 145 | } 146 | else{ 147 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 148 | } 149 | } 150 | 151 | 152 | public function whereGreaterThan($key,$value){ 153 | if(isset($key) && isset($value)){ 154 | $this->_query[$key] = array( 155 | '$gt' => $value 156 | ); 157 | } 158 | else{ 159 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 160 | } 161 | 162 | } 163 | 164 | public function whereLessThan($key,$value){ 165 | if(isset($key) && isset($value)){ 166 | $this->_query[$key] = array( 167 | '$lt' => $value 168 | ); 169 | } 170 | else{ 171 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 172 | } 173 | 174 | } 175 | 176 | public function whereGreaterThanOrEqualTo($key,$value){ 177 | if(isset($key) && isset($value)){ 178 | $this->_query[$key] = array( 179 | '$gte' => $value 180 | ); 181 | } 182 | else{ 183 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 184 | } 185 | 186 | } 187 | 188 | public function whereLessThanOrEqualTo($key,$value){ 189 | if(isset($key) && isset($value)){ 190 | $this->_query[$key] = array( 191 | '$lte' => $value 192 | ); 193 | } 194 | else{ 195 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 196 | } 197 | 198 | } 199 | 200 | public function whereAll($key,$value){ 201 | if(isset($key) && isset($value)){ 202 | if(is_array($value)){ 203 | $this->_query[$key] = array( 204 | '$all' => $value 205 | ); 206 | } 207 | else{ 208 | $this->throwError('$value must be an array to check through'); 209 | } 210 | } 211 | else{ 212 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 213 | } 214 | 215 | } 216 | 217 | 218 | public function whereContainedIn($key,$value){ 219 | if(isset($key) && isset($value)){ 220 | if(is_array($value)){ 221 | $this->_query[$key] = array( 222 | '$in' => $value 223 | ); 224 | } 225 | else{ 226 | $this->throwError('$value must be an array to check through'); 227 | } 228 | } 229 | else{ 230 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 231 | } 232 | 233 | } 234 | 235 | public function whereNotContainedIn($key,$value){ 236 | if(isset($key) && isset($value)){ 237 | if(is_array($value)){ 238 | $this->_query[$key] = array( 239 | '$nin' => $value 240 | ); 241 | } 242 | else{ 243 | $this->throwError('$value must be an array to check through'); 244 | } 245 | } 246 | else{ 247 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 248 | } 249 | 250 | } 251 | 252 | public function whereExists($key){ 253 | if(isset($key)){ 254 | $this->_query[$key] = array( 255 | '$exists' => true 256 | ); 257 | } 258 | } 259 | 260 | public function whereDoesNotExist($key){ 261 | if(isset($key)){ 262 | $this->_query[$key] = array( 263 | '$exists' => false 264 | ); 265 | } 266 | } 267 | 268 | public function whereRegex($key,$value,$options=''){ 269 | if(isset($key) && isset($value)){ 270 | $this->_query[$key] = array( 271 | '$regex' => $value 272 | ); 273 | 274 | if(!empty($options)){ 275 | $this->_query[$key]['options'] = $options; 276 | } 277 | } 278 | else{ 279 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 280 | } 281 | 282 | } 283 | 284 | public function wherePointer($key,$className,$objectId){ 285 | if(isset($key) && isset($className)){ 286 | $this->_query[$key] = $this->dataType('pointer', array($className,$objectId)); 287 | } 288 | else{ 289 | $this->throwError('the $key and $className parameters must be set when setting a "where" pointer query method'); 290 | } 291 | 292 | } 293 | 294 | public function whereInQuery($key,$className,$inQuery){ 295 | if(isset($key) && isset($className)){ 296 | $this->_query[$key] = array( 297 | '$inQuery' => $inQuery, 298 | 'className' => $className 299 | ); 300 | } 301 | else{ 302 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 303 | } 304 | 305 | } 306 | 307 | public function whereNotInQuery($key,$className,$inQuery){ 308 | if(isset($key) && isset($className)){ 309 | $this->_query[$key] = array( 310 | '$notInQuery' => $inQuery, 311 | 'className' => $className 312 | ); 313 | } 314 | else{ 315 | $this->throwError('the $key and $value parameters must be set when setting a "where" query method'); 316 | } 317 | 318 | } 319 | } 320 | 321 | ?> 322 | -------------------------------------------------------------------------------- /parseUser.php: -------------------------------------------------------------------------------- 1 | data[$name] = $value; 9 | } 10 | 11 | public function signup($username='',$password=''){ 12 | if($username != '' && $password != ''){ 13 | $this->username = $username; 14 | $this->password = $password; 15 | } 16 | 17 | if($this->data['username'] != '' && $this->data['password'] != ''){ 18 | $request = $this->request(array( 19 | 'method' => 'POST', 20 | 'requestUrl' => 'users', 21 | 'data' => $this->data 22 | )); 23 | 24 | return $request; 25 | 26 | } 27 | else{ 28 | $this->throwError('username and password fields are required for the signup method'); 29 | } 30 | 31 | } 32 | 33 | public function login(){ 34 | if(!empty($this->data['username']) || !empty($this->data['password']) ){ 35 | $request = $this->request(array( 36 | 'method' => 'GET', 37 | 'requestUrl' => 'login', 38 | 'data' => array( 39 | 'password' => $this->data['password'], 40 | 'username' => $this->data['username'] 41 | ) 42 | )); 43 | 44 | return $request; 45 | 46 | } 47 | else{ 48 | $this->throwError('username and password field are required for the login method'); 49 | } 50 | 51 | } 52 | 53 | public function socialLogin(){ 54 | if(!empty($this->authData)){ 55 | $request = $this->request( array( 56 | 'method' => 'POST', 57 | 'requestUrl' => 'users', 58 | 'data' => array( 59 | 'authData' => $this->authData 60 | ) 61 | )); 62 | return $request; 63 | } 64 | else{ 65 | $this->throwError('authArray must be set use addAuthData method'); 66 | } 67 | } 68 | 69 | public function get($objectId){ 70 | if($objectId != ''){ 71 | $request = $this->request(array( 72 | 'method' => 'GET', 73 | 'requestUrl' => 'users/'.$objectId, 74 | )); 75 | 76 | return $request; 77 | 78 | } 79 | else{ 80 | $this->throwError('objectId is required for the get method'); 81 | } 82 | 83 | } 84 | //TODO: should make the parseUser contruct accept the objectId and update and delete would only require the sessionToken 85 | public function update($objectId,$sessionToken){ 86 | if(!empty($objectId) || !empty($sessionToken)){ 87 | $request = $this->request(array( 88 | 'method' => 'PUT', 89 | 'requestUrl' => 'users/'.$objectId, 90 | 'sessionToken' => $sessionToken, 91 | 'data' => $this->data 92 | )); 93 | 94 | return $request; 95 | } 96 | else{ 97 | $this->throwError('objectId and sessionToken are required for the update method'); 98 | } 99 | 100 | } 101 | 102 | public function delete($objectId,$sessionToken){ 103 | if(!empty($objectId) || !empty($sessionToken)){ 104 | $request = $this->request(array( 105 | 'method' => 'DELETE', 106 | 'requestUrl' => 'users/'.$objectId, 107 | 'sessionToken' => $sessionToken 108 | )); 109 | 110 | return $request; 111 | } 112 | else{ 113 | $this->throwError('objectId and sessionToken are required for the delete method'); 114 | } 115 | 116 | } 117 | 118 | public function addAuthData($authArray){ 119 | if(is_array($authArray)){ 120 | $this->authData[$authArray['type']] = $authArray['authData']; 121 | } 122 | else{ 123 | $this->throwError('authArray must be an array containing a type key and a authData key in the addAuthData method'); 124 | } 125 | } 126 | 127 | public function linkAccounts($objectId,$sessionToken){ 128 | if(!empty($objectId) || !empty($sessionToken)){ 129 | $request = $this->request( array( 130 | 'method' => 'PUT', 131 | 'requestUrl' => 'users/'.$objectId, 132 | 'sessionToken' => $sessionToken, 133 | 'data' => array( 134 | 'authData' => $this->authData 135 | ) 136 | )); 137 | 138 | return $request; 139 | } 140 | else{ 141 | $this->throwError('objectId and sessionToken are required for the linkAccounts method'); 142 | } 143 | } 144 | 145 | public function unlinkAccount($objectId,$sessionToken,$type){ 146 | $linkedAccount[$type] = null; 147 | 148 | if(!empty($objectId) || !empty($sessionToken)){ 149 | $request = $this->request( array( 150 | 'method' => 'PUT', 151 | 'requestUrl' => 'users/'.$objectId, 152 | 'sessionToken' => $sessionToken, 153 | 'data' => array( 154 | 'authData' => $linkedAccount 155 | ) 156 | )); 157 | 158 | return $request; 159 | } 160 | else{ 161 | $this->throwError('objectId and sessionToken are required for the linkAccounts method'); 162 | } 163 | 164 | } 165 | 166 | public function requestPasswordReset($email){ 167 | if(!empty($email)){ 168 | $this->email - $email; 169 | $request = $this->request(array( 170 | 'method' => 'POST', 171 | 'requestUrl' => 'requestPasswordReset', 172 | 'email' => $email, 173 | 'data' => $this->data 174 | )); 175 | 176 | return $request; 177 | } 178 | else{ 179 | $this->throwError('email is required for the requestPasswordReset method'); 180 | } 181 | 182 | } 183 | 184 | 185 | } 186 | 187 | ?> -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/parseFileTest.php: -------------------------------------------------------------------------------- 1 | save('hello.txt'); 11 | 12 | \Enhance\Assert::isTrue( property_exists($save,'name') ); 13 | } 14 | 15 | public function deleteWithUrlExpectTrue(){ 16 | $file = new parseFile('text/plain','Working at Parse is great!'); 17 | $save = $file->save('hello.txt'); 18 | 19 | //SET BOTH ARGUMENTS BELOW TO FALSE, SINCE WE ARE DELETING A FILE, NOT SAVING ONE 20 | $todelete = new parseFile; 21 | $return = $todelete->delete($save->name); 22 | 23 | \Enhance\Assert::isTrue( $return ); 24 | } 25 | 26 | } 27 | 28 | ?> -------------------------------------------------------------------------------- /tests/parseGeoPointTest.php: -------------------------------------------------------------------------------- 1 | location) ); 11 | } 12 | 13 | } 14 | 15 | ?> -------------------------------------------------------------------------------- /tests/parseObjectTest.php: -------------------------------------------------------------------------------- 1 | parseObject = new parseObject('test'); 8 | $this->parseObject = \Enhance\Core::getCodeCoverageWrapper('parseObject', array('test')); 9 | $this->testfield1 = 'test1'; 10 | $this->testfield2 = 'test2'; 11 | } 12 | 13 | public function saveWithTestfield1ExpectObjectId(){ 14 | $parseObject = $this->parseObject; 15 | $parseObject->testfield1 = $this->testfield1; 16 | $return = $parseObject->save(); 17 | 18 | \Enhance\Assert::isTrue( property_exists($return,'objectId') ); 19 | } 20 | 21 | public function getWithObjectIdExpectTest1(){ 22 | $parseObject = $this->parseObject; 23 | $parseObject->testfield2 = $this->testfield2; 24 | $save = $parseObject->save(); 25 | 26 | $return = $parseObject->get($save->objectId); 27 | 28 | \Enhance\Assert::areIdentical('test2', $return->testfield2); 29 | } 30 | 31 | public function updateWithObjectIdExpectupdatedAt(){ 32 | $parseObject = $this->parseObject; 33 | $parseObject->testfield2 = $this->testfield2; 34 | $save = $parseObject->save(); 35 | 36 | $updateObject = new parseObject('test'); 37 | $updateObject->testfield2 = 'updated test2'; 38 | $return = $parseObject->update($save->objectId); 39 | 40 | \Enhance\Assert::isTrue( property_exists($return, 'updatedAt') ); 41 | } 42 | 43 | public function deleteWithObjectIdExpectEmpty(){ 44 | $parseObject = $this->parseObject; 45 | $parseObject->testfield1 = $this->testfield2; 46 | $save = $parseObject->save(); 47 | 48 | $return = $parseObject->delete($save->objectId); 49 | 50 | \Enhance\Assert::isTrue( $return ); 51 | } 52 | 53 | } 54 | 55 | ?> -------------------------------------------------------------------------------- /tests/parsePushTest.php: -------------------------------------------------------------------------------- 1 | send(); 10 | 11 | \Enhance\Assert::isTrue( $return ); 12 | } 13 | 14 | public function sendWithDataExpectTrue(){ 15 | $parsePush = \Enhance\Core::getCodeCoverageWrapper('parsePush'); 16 | 17 | //$parsePush->channel = 'TEST_CHANNEL_ONE'; //this or channels required 18 | $parsePush->channels = array('TEST_CHANNEL_ONE','TEST_CHANNEL_TWO'); //this or just channel required 19 | $parsePush->alert = 'Testing Channel 1'; //required 20 | 21 | //BELOW SETTINGS ARE OPTIONAL, LOOKUP REST API DOCS HERE: http://parse.com/docs/rest#push FOR MORE INFO 22 | $parsePush->expiration_time = time( strtotime('+3 days') ); //expire 3 day from now 23 | //$parsePush->expiration_time_interval = 86400; //expire in 24 hours from now 24 | $parsePush->type = 'ios'; 25 | $parsePush->badge = 538; //ios only 26 | $parsePush->sound = 'cheer'; //ios only 27 | $parsePush->content_available = 1; //ios only - for newsstand applications. Also, changed from content-available to content_available. 28 | //$parsePush->title = 'test notification title'; //android only - gives title to the notification 29 | 30 | //CUSTOM DATA CAN BE SENT VERY EASILY ALONG WITH YOUR NOTIFICATION MESSAGE AND CAN BE ACCESSED PROGRAMATICALLY VIA THE MOBILE DEVICE... JUST DON'T SET NAMES THE SAME AS RESERVERD ONES MENTIONED ABOVE 31 | $parsePush->customData = 'This data will be accessible in the ios and android SDK callback for push notifications'; 32 | 33 | $return = $parsePush->send(); 34 | 35 | \Enhance\Assert::isTrue( $return ); 36 | } 37 | 38 | } 39 | 40 | ?> -------------------------------------------------------------------------------- /tests/parseQueryTest.php: -------------------------------------------------------------------------------- 1 | score = 1111; 14 | $parseObject->name = 'Foo'; 15 | $parseObject->mode = 'cheat'; 16 | $this->parseObject = $parseObject->save(); 17 | 18 | $parseObject2 = new parseObject('test'); 19 | $parseObject2->score = 2222; 20 | $parseObject2->name = 'Bar'; 21 | $parseObject2->mode = 'nocheat'; 22 | $parseObject2->phone = '555-555-1234'; 23 | $parseObject2->object1 = $parseObject2->dataType('pointer', array('test',$this->parseObject->objectId)); 24 | $this->parseObject2 = $parseObject2->save(); 25 | 26 | $this->parseQuery = \Enhance\Core::getCodeCoverageWrapper('parseQuery', array('test')); 27 | $this->parseQueryUser = \Enhance\Core::getCodeCoverageWrapper('parseQuery', array('users')); 28 | 29 | } 30 | 31 | public function findWithNameExpectResults(){ 32 | $parseQuery = $this->parseQuery; 33 | $parseQuery->where('name','Foo'); 34 | $return = $parseQuery->find(); 35 | 36 | \Enhance\Assert::isTrue( is_array($return->results) ); 37 | } 38 | 39 | public function findWithNameNotExpectResults(){ 40 | $parseQuery = $this->parseQuery; 41 | $parseQuery->whereNotEqualTo('name','Foo'); 42 | $return = $parseQuery->find(); 43 | 44 | \Enhance\Assert::isTrue( is_array($return->results) ); 45 | } 46 | 47 | public function findWithScoreGreaterExpectResults(){ 48 | $parseQuery = $this->parseQuery; 49 | $parseQuery->whereGreaterThan('score',1500); 50 | $return = $parseQuery->find(); 51 | 52 | \Enhance\Assert::isTrue( is_array($return->results) ); 53 | } 54 | 55 | public function findWithScoreLessExpectResults(){ 56 | $parseQuery = $this->parseQuery; 57 | $parseQuery->whereLessThan('score',1500); 58 | $return = $parseQuery->find(); 59 | 60 | \Enhance\Assert::isTrue( is_array($return->results) ); 61 | } 62 | 63 | public function findWithScoreGreaterOrEqualExpectResults(){ 64 | $parseQuery = $this->parseQuery; 65 | $parseQuery->whereGreaterThanOrEqualTo('score',1111); 66 | $return = $parseQuery->find(); 67 | 68 | \Enhance\Assert::isTrue( is_array($return->results) ); 69 | } 70 | 71 | public function findWithScoreLessOrEqualExpectResults(){ 72 | $parseQuery = $this->parseQuery; 73 | $parseQuery->whereLessThanOrEqualTo('score',1111); 74 | $return = $parseQuery->find(); 75 | 76 | \Enhance\Assert::isTrue( is_array($return->results) ); 77 | } 78 | 79 | public function findWithModeContainedInExpectResults(){ 80 | $parseQuery = $this->parseQuery; 81 | $parseQuery->whereContainedIn('mode',array('cheat','test','mode')); 82 | $return = $parseQuery->find(); 83 | 84 | \Enhance\Assert::isTrue( is_array($return->results) ); 85 | } 86 | 87 | public function findWithNameNotContainedInExpectResults(){ 88 | $parseQuery = $this->parseQuery; 89 | $parseQuery->whereNotContainedIn('name',array('cheat','test','mode')); 90 | $return = $parseQuery->find(); 91 | 92 | \Enhance\Assert::isTrue( is_array($return->results) ); 93 | } 94 | 95 | public function findWithScoreExistsExpectResults(){ 96 | $parseQuery = $this->parseQuery; 97 | $parseQuery->whereExists('score'); 98 | $return = $parseQuery->find(); 99 | 100 | \Enhance\Assert::isTrue( is_array($return->results) ); 101 | } 102 | 103 | public function findWithScoreDoesNotExistExpectResults(){ 104 | $parseQuery = $this->parseQuery; 105 | $parseQuery->whereDoesNotExist('score'); 106 | $return = $parseQuery->find(); 107 | 108 | \Enhance\Assert::isTrue( is_array($return->results) ); 109 | } 110 | 111 | public function findWithRegexExpectResults(){ 112 | $parseQuery = $this->parseQuery; 113 | $parseQuery->whereRegex('name','^\bF.*'); 114 | $return = $parseQuery->find(); 115 | 116 | \Enhance\Assert::isTrue( is_array($return->results) ); 117 | } 118 | 119 | public function findWithInQueryExpectResults(){ 120 | $parseQuery = $this->parseQuery; 121 | $parseQuery->whereInQuery('object1','test', array('where' => array( 122 | 'name' => array('$exists' => true) 123 | ))); 124 | $return = $parseQuery->find(); 125 | 126 | \Enhance\Assert::isTrue( is_array($return->results) ); 127 | } 128 | 129 | public function findWithNotInQueryExpectResults(){ 130 | $parseQuery = $this->parseQuery; 131 | $parseQuery->whereNotInQuery('object1','test', array('where' => array( 132 | 'name' => array('$exists' => true) 133 | ))); 134 | $return = $parseQuery->find(); 135 | 136 | \Enhance\Assert::isTrue( is_array($return->results) ); 137 | } 138 | 139 | 140 | 141 | 142 | } 143 | ?> -------------------------------------------------------------------------------- /tests/parseUserTest.php: -------------------------------------------------------------------------------- 1 | parseUser = new parseUser; 9 | $this->testUser = array( 10 | 'username' => 'testUser'.rand(), 11 | 'password' => 'testPass', 12 | 'email' => 'testUser@parse.com', 13 | 'customField' => 'customValue' 14 | ); 15 | 16 | } 17 | 18 | public function signupWithTestuserExpectObjectId(){ 19 | $parseUser = $this->parseUser; 20 | 21 | $return = $parseUser->signup($this->testUser['username'], $this->testUser['password']); 22 | 23 | //print_r($return); 24 | 25 | $deleteUser = new parseUser; 26 | $deleteUser->delete($return->objectId,$return->sessionToken); 27 | 28 | \Enhance\Assert::isTrue( property_exists($return,'objectId') ); 29 | 30 | } 31 | 32 | public function signupWithEmailAndCustomFieldExpectObjectId(){ 33 | $parseUser = $this->parseUser; 34 | $parseUser->username = $this->testUser['username']; 35 | $parseUser->password = $this->testUser['password']; 36 | $parseUser->email = $this->testUser['email']; 37 | $parseUser->customField = $this->testUser['customField']; 38 | 39 | $return = $parseUser->signup(); 40 | 41 | $deleteUser = new parseUser; 42 | $deleteUser->delete((string)$return->objectId,(string)$return->sessionToken); 43 | 44 | \Enhance\Assert::isTrue( property_exists($return,'objectId') ); 45 | 46 | } 47 | 48 | public function loginWithUsernameAndPasswordExpectObjectId(){ 49 | $parseUser = $this->parseUser; 50 | $parseUser->username = $this->testUser['username']; 51 | $parseUser->password = $this->testUser['password']; 52 | 53 | $return = $parseUser->signup(); 54 | 55 | $loginUser = new parseUser; 56 | $loginUser->username = $this->testUser['username']; 57 | $loginUser->password = $this->testUser['password']; 58 | 59 | $returnLogin = $loginUser->login(); 60 | 61 | $deleteUser = new parseUser; 62 | $deleteUser->delete((string)$return->objectId,(string)$return->sessionToken); 63 | 64 | \Enhance\Assert::isTrue( property_exists($returnLogin,'objectId') ); 65 | } 66 | 67 | public function getUserWithObjectIdExpectUsername(){ 68 | $testUser = new parseUser; 69 | $testUser->username = $this->testUser['username']; 70 | $testUser->password = $this->testUser['password']; 71 | 72 | //need to clear properties after a call like this to make sure username/password aren't used for the get command below 73 | $user = $testUser->signup(); 74 | 75 | $parseUser = new parseUser; 76 | $return = $parseUser->get($user->objectId); 77 | 78 | \Enhance\Assert::isTrue( property_exists($return,'username') ); 79 | } 80 | 81 | public function queryUsersWithQueryExpectResultsKey(){ 82 | $parseUser = $this->parseUser; 83 | $userQuery = new parseQuery('users'); 84 | $userQuery->whereExists('phone'); 85 | $return = $userQuery->find(); 86 | 87 | \Enhance\Assert::isTrue( property_exists($return, 'results') ); 88 | 89 | } 90 | 91 | public function deleteWithObjectIdExpectTrue(){ 92 | $testUser = new parseUser; 93 | $testUser->username = $this->testUser['username']; 94 | $testUser->password = $this->testUser['password']; 95 | 96 | $user = $testUser->signup(); 97 | 98 | $parseUser = $this->parseUser; 99 | $return = $parseUser->delete($user->objectId,$user->sessionToken); 100 | 101 | \Enhance\Assert::isTrue( $return ); 102 | } 103 | /* 104 | THESE TESTS RETURN ERROR EVERYTIME FROM PARSE BECAUSE OF AN INVALID FACEBOOK ID 105 | 106 | public function linkAccountsWithAddAuthDataExpectTrue(){ 107 | $testUser = new parseUser; 108 | $testUser->username = $this->testUser['username']; 109 | $testUser->password = $this->testUser['password']; 110 | 111 | $user = $testUser->signup(); 112 | 113 | $parseUser = new parseUser; 114 | 115 | //These technically don't have to be REAL, unless you want them to actually work :) 116 | $parseUser->addAuthData(array( 117 | 'type' => 'facebook', 118 | 'authData' => array( 119 | 'id' => 'FACEBOOK_ID_HERE', 120 | 'access_token' => 'FACEBOOK_ACCESS_TOKEN', 121 | 'expiration_date' => "2012-12-28T23:49:36.353Z" 122 | ) 123 | )); 124 | 125 | $parseUser->addAuthData(array( 126 | 'type' => 'twitter', 127 | 'authData' => array( 128 | 'id' => 'TWITTER_ID', 129 | 'screen_name' => 'TWITTER_SCREEN_NAME', 130 | 'consumer_key' => 'CONSUMER_KEY', 131 | 'consumer_secret' => 'CONSUMER_SECRET', 132 | 'auth_token' => 'AUTH_TOKEN', 133 | 'auth_token_secret' => 'AUTH_TOKEN_SECRET', 134 | ) 135 | )); 136 | 137 | $return = $parseUser->linkAccounts($user->objectId,$user->sessionToken); 138 | 139 | \Enhance\Assert::isTrue( $return ); 140 | } 141 | 142 | 143 | public function unlinkAccountWith(){ 144 | 145 | } 146 | */ 147 | 148 | } 149 | 150 | ?> --------------------------------------------------------------------------------