EDITED to add code for MainClass as requested in comments.
I'm trying to learn how to make php packages and how to use phpunit at the same time, I may be using all the wrong terminology here and doing everything wrong..
Everything works as expected when I import the package with composer. I decided to add some unit tests as I finally started to see how they could be useful to me however I am having trouble and I suspect it has something to do with namespaces but I'm not sure.
I have put the tests in their own directory and used use statements at the top of the test classes for importing the main src classes. So, for example, in a test class I have the following:
use myname\Package\MainClass;
use myname\Package\Resources\Resource;
use myname\Package\Resources\ExtendedResource;
class ResourceTest extends PHPUnit_Framework_TestCase {
public function testArtistIsResource() {
$resource = '\\myname\\Package\\Resources\\Resource';
$main = new MainClass('Artist');
$artist = $main->find(1383508);
$this->assertTrue($artist instanceof $resource);
}
}
This test passes. I am running the same code outside of the test directory and displaying values in the browser to see what happens. I am running the package in laravel and just running the comparison code on the homepage. For example the output of the following code is printed directly in the browser
$main = new MainClass('Artist');
$artist = $main->find(1383508);
echo get_class($main);
echo get_class($artist);
This shows that $main is a myname\Package\MainClass and $artist is a myname\Package\Resources\ExtendedResource. If I change the second echo statement above to this:
echo get_class($artist->get());
Then the result is that stdClass is echoed to the screen, which is correct. However in the test class $artist->get() returns an instance of ResourceTest and I don't understand why it is not another stdClass.
What am I missing?
My directory structure is as follows:
myname
|- Package
|- composer.json
|- src
|- MainClass.php
|- Resources
|- Resource.php
|- ExtendsResource.php
|- tests
|- Resources
|- ResourceTest.php
Below is the content of the autoload part of composer.json
"autoload": {
"psr-4": {
"myname\\Package\\": "src/"
}
}
I tried adding another namespace in there - "myname\Package\tests\": "tests/" - but that didn't seem to help.
The namespace for MainClass.php is myname\Package.
The namespace for Resources.php and ExtendsResources.php is myname\Package\Resources.
Here is the code for MainClass.php
<?php
namespace myname\Package;
class MainClass {
private $resource;
public function __construct($resource = null) {
Container::setup();
if ($resource) {
$this->resource = Container::get($resource);
}
return $this->resource;
}
public function find($id) {
if (isset ($this->resource)) {
$this->resource->find($id);
return $this->resource;
}
else { throw new \Exception('Resource is not set'); }
}
public function setResource($resource) {
$this->resource = Container::get($resource);
return $this->resource;
}
}
Below is the code for myname\Package\Resources\Reource
<?php
namespace myname\Package\Resources;
use myname\Package\Contracts\ConfigInterface;
use myname\Package\Contracts\GrabberInterface;
use myname\Package\Contracts\ResourceInterface;
use myname\Package\Http\Grabber;
use myname\Package\Http\Poster;
abstract class Resource {
protected $config = null;
protected $url = null;
protected $resource = null;
protected $response = null;
protected $grabber = null;
protected $perPage = null;
protected $page = null;
protected $params = null;
protected $token = null;
protected $identifier = null;
protected $update = array();
protected $appendTokenTo = array(
'myname\Package\Resources\Artist',
'myname\Package\Resources\Listing',
'myname\Package\Resources\Release',
'myname\Package\Resources\Search'
);
public function __construct($config, $grabber) {
if ($config instanceof ConfigInterface) {
$this->config = $config;
} else { throw new \Exception('The supplied $config is not an instance of ConfigInterface'); }
if ($grabber instanceof GrabberInterface) {
$this->grabber = $grabber;
} else { throw new \Exception('The supplied $grabber is not an instance of GrabberInterface'); }
$this->url .= $this->config->getApiUrl() . $this->resource;
$this->token = $this->config->getApiToken();
return $this;
}
public function addParam($param, $value) {
$value= $this->formatParamValue($value);
$this->params .= "&". "$param=$value";
return $this;
}
protected function addToken(){
$this->addParam('token', $this->token);
//$this->params .= "&". "token=$this->token";
return $this;
}
public function addUpdate($update, $value) {
$this->update[$update] = $value;
return $this;
}
protected function checkIfTokenIsRequired() {
if (in_array(get_class($this), $this->appendTokenTo)) {
$this->addToken();
}
}
public function find($identifier) {
if (empty ($this->identifier)) {
$this->identifier = $identifier;
$this->url .= "/$identifier";
}
return $this;
}
protected function formatParamValue($value) {
$value = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
$value = str_replace(' ', '+', $value);
return $value;
}
public function get() {
return json_decode($this->getResponse());
}
protected function getResponse() {
if (!isset($this->response)) {
$this->checkIfTokenIsRequired();
$this->_prepare();
}
return $this->response;
}
public function json() {
return $this->getResponse();
}
public function page($pageNumber) {
$this->page = $pageNumber;
return $this;
}
public function perPage($resultsPerPage) {
$this->perPage = $resultsPerPage;
return $this;
}
protected function _prepare() {
$params = 0;
if (isset($this->page) OR isset($this->perPage) OR isset($this->params)){
$this->url .= '?';
}
if (isset($this->params)) {
$this->url .= "$this->params";
$params++;
}
if (isset($this->perPage)) {
if ($params > 0) {
$this->url .= '&';
}
$this->url .= "per_page=$this->perPage";
$params++;
}
if (isset($this->page)) {
if ($params > 0) {
$this->url .= '&';
}
$this->url .= "page=$this->page";
$params++;
}
$this->grabber->setUrl($this->url);
$this->response = $this->grabber->grab();
}
public function setGrabber($grabber) {
if ($grabber instanceof GrabberInterface) {
$this->grabber = $grabber;
} else { throw new \Exception($grabber . " is not an instance of GrabberInterface"); }
}
public function setUrl($url) {
$this->url = $url;
}
public function update() {
//$this->update['token'] = $this->token;
$this->grabber->setMethod('POST');
$this->grabber->setUpdates(json_encode($this->update));
$this->_prepare();
return $this;
}
}
Below is the code for the ExtendedResource
<?php
namespace myname\Package\Resources;
class ExtendedResource extends Resource {
protected $resource = 'artists';
/**
* Returns the releases associated with an artist
*
* @return $this
*/
public function releases() {
$this->url .= '/releases';
return $this;
}
}