/**
  * @param mixed $data
  * @return mixed[] associative array of properties
  */
 protected function getProperties($data)
 {
     $extractor = new ObjectPropertyExtractor($data);
     // Call __sleep if present
     if (method_exists($data, '__sleep')) {
         $properties = call_user_func([$data, '__sleep']);
     } else {
         $properties = $extractor->getProperties();
     }
     $values = $extractor->getValues($properties);
     // Call __wakeup if present to restore previous state
     if (method_exists($data, '__wakeup')) {
         call_user_func([$data, '__wakeup']);
     }
     return $values;
 }
 public function testExtraction()
 {
     require_once __DIR__ . '/Mocks/TestBaseClass.php';
     require_once __DIR__ . '/Mocks/TestSubClass.php';
     $objWithInheritance = new TestSubClass();
     $SUT = new ObjectPropertyExtractor($objWithInheritance);
     $extractedProperties = $SUT->getProperties();
     // We expect 7 properties, no static properties
     $this->assertCount(7, $extractedProperties);
     // Check if all expected properties are indexed
     $this->assertContains('privateSubVar', $extractedProperties);
     $this->assertContains('protectedSubVar', $extractedProperties);
     $this->assertContains('publicSubVar', $extractedProperties);
     $this->assertContains('overriddenBaseVar', $extractedProperties);
     $this->assertContains('protectedBaseVar', $extractedProperties);
     $this->assertContains('publicBaseVar', $extractedProperties);
     $this->assertContains('privateBaseVar', $extractedProperties);
     // Check if value of overridden property is the one of the sub class
     $overriddenBaseVar = $SUT->getValue('overriddenBaseVar');
     $this->assertEquals('def', $overriddenBaseVar);
 }