Page MenuHomeDevCentral

No OneTemporary

diff --git a/includes/autoload.php b/includes/autoload.php
index 84aa174..fde5ae7 100644
--- a/includes/autoload.php
+++ b/includes/autoload.php
@@ -1,89 +1,90 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Classes and interfaces auto loader
*
* @package ObsidianWorkspaces
* @filesource
*/
/**
* This SPL autoloader method is called when a class or an interface can't be loaded.
*/
function obsidian_autoload ($name) {
$dir = dirname(__DIR__);
///
/// Applications
///
if ($name == 'DocumentsApplication') { require $dir . '/apps/documents/DocumentsApplication.php'; return true; }
if ($name == 'DocumentsApplicationConfiguration') { require $dir . '/apps/documents/DocumentsApplicationConfiguration.php'; return true; }
if ($name == 'HelloWorldApplication') { require $dir . '/apps/helloworld/HelloWorldApplication.php'; return true; }
if ($name == 'MediaWikiMirrorApplication') { require $dir . '/apps/mediawikimirror/MediaWikiMirrorApplication.php'; return true; }
if ($name == 'MediaWikiMirrorApplicationConfiguration') { require $dir . '/apps/mediawikimirror/MediaWikiMirrorApplicationConfiguration.php'; return true; }
if ($name == 'StaticContentApplication') { require $dir . '/apps/staticcontent/StaticContentApplication.php'; return true; }
if ($name == 'StaticContentApplicationConfiguration') { require $dir . '/apps/staticcontent/StaticContentApplicationConfiguration.php'; return true; }
///
/// Core controllers
///
if ($name == 'ErrorPageController') { require $dir . '/controllers/errorpage.php'; return true; }
if ($name == 'FooterController') { require $dir . '/controllers/footer.php'; return true; }
if ($name == 'HeaderController') { require $dir . '/controllers/header.php'; return true; }
if ($name == 'HomepageController') { require $dir . '/controllers/home.php'; return true; }
///
/// Keruald and Obsidian Workspaces libraries
///
if ($name == 'ObjectDeserializable') { require $dir . '/includes/ObjectDeserializable.php'; return true; }
if ($name == 'ObjectDeserializableWithContext') { require $dir . '/includes/ObjectDeserializable.php'; return true; }
if ($name == 'Application') { require $dir . '/includes/apps/Application.php'; return true; }
if ($name == 'ApplicationConfiguration') { require $dir . '/includes/apps/ApplicationConfiguration.php'; return true; }
if ($name == 'ApplicationContext') { require $dir . '/includes/apps/ApplicationContext.php'; return true; }
if ($name == 'AddToGroupUserAction') { require $dir . '/includes/auth/AddToGroupUserAction.php'; return true; }
if ($name == 'AuthenticationMethod') { require $dir . '/includes/auth/AuthenticationMethod.php'; return true; }
if ($name == 'AzharProvider') { require $dir . '/includes/auth/AzharProvider.php'; return true; }
if ($name == 'GivePermissionUserAction') { require $dir . '/includes/auth/GivePermissionUserAction.php'; return true; }
if ($name == 'UserAction') { require $dir . '/includes/auth/UserAction.php'; return true; }
if ($name == 'Cache') { require $dir . '/includes/cache/cache.php'; return true; }
if ($name == 'CacheMemcached') { require $dir . '/includes/cache/memcached.php'; return true; }
if ($name == 'CacheVoid') { require $dir . '/includes/cache/void.php'; return true; }
if ($name == 'Collection') { require $dir . '/includes/collection/Collection.php'; return true; }
if ($name == 'CollectionDocument') { require $dir . '/includes/collection/CollectionDocument.php'; return true; }
if ($name == 'FilesCollection') { require $dir . '/includes/collection/FilesCollection.php'; return true; }
if ($name == 'MongoDBCollection') { require $dir . '/includes/collection/MongoDBCollection.php'; return true; }
+ if ($name == 'MongoDBCollectionIterator') { require $dir . '/includes/collection/MongoDBCollectionIterator.php'; return true; }
if ($name == 'Context') { require $dir . '/includes/controller/Context.php'; return true; }
if ($name == 'Controller') { require $dir . '/includes/controller/Controller.php'; return true; }
if ($name == 'RunnableWithContext') { require $dir . '/includes/controller/RunnableWithContext.php'; return true; }
if ($name == 'Message') { require $dir . '/includes/i18n/Message.php'; return true; }
if ($name == 'TextFileMessage') { require $dir . '/includes/i18n/TextFileMessage.php'; return true; }
if ($name == 'Disclaimer') { require $dir . '/includes/objects/Disclaimer.php'; return true; }
if ($name == 'Permission') { require $dir . '/includes/objects/Permission.php'; return true; }
if ($name == 'User') { require $dir . '/includes/objects/user.php'; return true; }
if ($name == 'UserGroup') { require $dir . '/includes/objects/usergroup.php'; return true; }
if ($name == 'Workspace') { require $dir . '/includes/workspaces/Workspace.php'; return true; }
if ($name == 'WorkspaceConfiguration') { require $dir . '/includes/workspaces/WorkspaceConfiguration.php'; return true; }
return false;
}
spl_autoload_register('obsidian_autoload');
diff --git a/includes/collection/Collection.php b/includes/collection/Collection.php
index fae0b44..12cc7fa 100644
--- a/includes/collection/Collection.php
+++ b/includes/collection/Collection.php
@@ -1,128 +1,142 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Collection class
*
* @package ObsidianWorkspaces
* @subpackage Collection
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Collection class
*
* This abstract class repreesnts a collection of documents
*/
abstract class Collection {
///
/// Common properties
///
/**
* @var string The collection identifiant
*/
public $id;
/**
* @var string the name of the document collection class to use
*/
public $documentType = 'CollectionDocument';
///
/// Factory
///
/**
* Loads a new instance of the collection
*
* @param string $id The collection identifiant
* @param string $documentType The type, inheriting from CollectionDocumt to use for ollection's documents
* @return Collection The collection, of the type specified in the storage configuration
*/
public static function load ($id, $documentType = null) {
global $Config;
if (!array_key_exists(('DocumentStorage'), $Config)) {
throw new Exception("Configuration required parameter missing: DocumentStorage");
}
if (!array_key_exists(('Type'), $Config['DocumentStorage'])) {
throw new Exception("Configuration required parameter missing in DocumentStorage array: Type");
}
$collectionClass = $Config['DocumentStorage']['Type'] . 'Collection';
if (!class_exists($collectionClass)) {
throw new Exception("Storage class not found: $collectionClass");
}
$instance = new $collectionClass($id);
if ($documentType !== null) {
$instance->documentType = $documentType;
}
return $instance;
}
///
/// CRUD features
///
/**
* Adds a document to the collection
*
* @param CollectionDocument $document The document to add
* @return boolean true if the operation succeeded; otherwise, false.
*/
public abstract function add (CollectionDocument &$document);
/**
* Deletes a document from the collection
*
* @param string $documentId The identifiant of the document to delete
* @return boolean true if the operation succeeded; otherwise, false.
*/
public abstract function delete ($documentId);
/**
* Determines if a document exists
*
* @param CollectionDocument $document The document to check
* @return boolean true if the document exists; otherwise, false.
*/
public abstract function exists (CollectionDocument $document);
/**
* Updates a document in the collection
*
* @param CollectionDocument $document The document to update
* @return boolean true if the operation succeeded; otherwise, false.
*/
public abstract function update (CollectionDocument &$document);
/**
* Gets a document from the collection
*
* @param string $documentId The identifiant of the document to get
* @param CollectionDocument $document The document
*/
public abstract function get ($documentId);
+ /**
+ * Gets a count of the documents in the collection
+ *
+ * @return int The number of documents
+ */
+ public abstract function count ();
+
+ /**
+ * Gets all the documents from the collection
+ *
+ * @return Traversable An iterator to the documents, each item an instance of CollectionDocument
+ */
+ public abstract function getAll ();
+
/**
* Adds or updates a document in the collection
*
* @param CollectionDocument $document The document to set
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function set (CollectionDocument &$document) {
if ($document->id !== null && $this->exists($document)) {
return $this->update($document);
} else {
return $this->add($document);
}
}
}
diff --git a/includes/collection/FilesCollection.php b/includes/collection/FilesCollection.php
index 0d9de15..f268ae2 100644
--- a/includes/collection/FilesCollection.php
+++ b/includes/collection/FilesCollection.php
@@ -1,172 +1,231 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Files Collection class
*
* @package ObsidianWorkspaces
* @subpackage Collection
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Files Collection class
*
* This class repreesnts a collection of documents, stored on the filesystem.
*/
class FilesCollection extends Collection {
///
/// Helper methods
///
/**
- * Gets the path to the folder where the specified collection id is stored.
+ * Gets the path to the folder where the specified collection documents are stored.
*
* @param string $collectionId The collection identifiant
* @return string The path to the specified collection folder
*/
public static function getCollectionPath ($collectionId) {
global $Config;
if (!array_key_exists('DocumentStorage', $Config) || !array_key_exists('Path', $Config['DocumentStorage'])) {
throw new Exception("Configuration parameter missing: \$Config['DocumentStorage']['Path']. Expected value for this parameter is the path to the collections folders.");
}
$path = $Config['DocumentStorage']['Path'] . DIRECTORY_SEPARATOR . $collectionId;
//Ensure directory exists. If not, creates it or throws an exception
if (!file_exists($path) && !mkdir($path, 0700, true)) {
throw new Exception("Directory doesn't exist and couldn't be created: $path");
}
return $path;
}
/**
- * Gets the path to the folder where the specified collection id is stored.
+ * Gets the path to the file where the specified document is stored.
*
* @param string $documentId The document identifiant
* @return string The path to the specified document file
*/
public function getDocumentPath ($documentId) {
return static::getCollectionPath($this->id) . DIRECTORY_SEPARATOR . $documentId . '.json';
}
+ /**
+ * Gets the path to the folder where the current collection is stored.
+ *
+ * @return string The path to the specified collection folder
+ */
+ public function getCurrentCollectionPath () {
+ return static::getCollectionPath($this->id);
+ }
+
///
/// Constructor
///
/**
* Initializes a new instance of MongoCollection
*
* @param string the database identifiant
*/
public function __construct ($id) {
$this->id = $id;
}
///
/// CRUD features
///
/**
* Adds a document to the collection
*
* @param CollectionDocument $document The document to add
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function add (CollectionDocument &$document) {
if ($document->id === '') {
$document->id = uniqid();
}
$filename = $this->getDocumentPath($document->id);
if (file_exists($filename)) {
throw new Exception("A document with the same identifiant is already in the collection, stored at $filename");
}
$data = json_encode($document);
file_put_contents($filename, $data);
}
/**
* Deletes a document from the collection
*
* @param string $documentId The identifiant of the document to delete
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function delete ($documentId) {
$filename = $this->getDocumentPath($documentId);
unlink($filename);
}
/**
* Determines if a document exists
*
* @param CollectionDocument $document The document to check
* @return boolean true if the document exists; otherwise, false.
*/
public function exists (CollectionDocument $document) {
$filename = $this->getDocumentPath($document->id);
return file_exists($filename);
}
/**
* Updates a document in the collection
*
* @param CollectionDocument $document The document to update
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function update (CollectionDocument &$document) {
if ($document->id === '') {
$document->id = uniqid();
user_error("An ID were expected for an update operation, but not provided. We'll use $document->id.", E_USER_WARNING);
}
$filename = $this->getDocumentPath($document->id);
if (!file_exists($filename)) {
user_error("File $filename doesn't exist. The update operation has became an insert one.", E_USER_WARNING);
}
$data = json_encode($document);
file_put_contents($filename, $data);
}
/**
* Gets a document from the collection
*
* @param string $documentId The identifiant of the document to get
* @param CollectionDocument $document The document
*/
public function get ($documentId) {
$type = $this->documentType;
if (!class_exists($type)) {
- throw new Exception("Can't create an instance of $type. If the class exists, did you registered a SPL autoloader or updated includes/autoload.php?");
+ throw new Exception("Can't create an instance of $type. If the class exists, did you register a SPL autoloader or updated includes/autoload.php?");
}
$filename = $this->getDocumentPath($documentId);
$data = json_decode(file_get_contents($filename));
return $type::loadFromObject($data);
}
/**
* Adds or updates a document in the collection
*
* @param CollectionDocument $document The document to set
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function set (CollectionDocument &$document) {
if ($document->id === '') {
$document->id = uniqid();
}
$filename = $this->getDocumentPath($document->id);
$data = json_encode($document);
file_put_contents($filename, $data);
}
-}
\ No newline at end of file
+
+ /**
+ * Gets a count of the documents in the collection
+ *
+ * @return int The number of documents
+ */
+ public function count () {
+ $dir = $this->getCurrentCollectionPath();
+ $count = 0;
+ $files = scandir($dir);
+ foreach ($files as $file) {
+ if (get_extension($file) == 'json') {
+ $count++;
+ }
+ }
+ return $count;
+ }
+
+ /**
+ * Gets all the documents from the collection
+ *
+ * @return Generator An iterator to the documents, each item an instance of CollectionDocument
+ */
+ public function getAll () {
+ $dir = $this->getCurrentCollectionPath();
+ $files = scandir($dir);
+ foreach ($files as $file) {
+ if (get_extension($file) == 'json') {
+ $documentId = get_filename($file);
+ yield $this->get($documentId);
+ }
+ }
+ }
+
+ /**
+ * Gets documents list
+ *
+ * @return array The documents list
+ */
+ public function getDocumentsList () {
+ $dir = $this->getFilePath('');
+ $files = scandir($dir);
+ $documents = [];
+ foreach ($files as $file) {
+ if (get_extension($file) == 'json') {
+ $documents[] = get_filename($file);
+ }
+ }
+ return $documents;
+ }
+}
diff --git a/includes/collection/MongoDBCollection.php b/includes/collection/MongoDBCollection.php
index f0345a6..ac0a650 100644
--- a/includes/collection/MongoDBCollection.php
+++ b/includes/collection/MongoDBCollection.php
@@ -1,238 +1,263 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* MongoDB Collection class
*
* @package ObsidianWorkspaces
* @subpackage Collection
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
define('MONGO_DEFAULT_HOST', 'localhost');
define('MONGO_DEFAULT_PORT', 27017);
define('MONGO_DEFAULT_DATABASE', 'obsidian');
/**
* MongoDB Collection class
*
* This class repreesnts a collection of documents, stored on MongoDB.
*/
class MongoDBCollection extends Collection {
/**
* @var MongoCollection the Mongo collection
*/
- private $mongoCollection;
+ public $mongoCollection;
///
/// Singleton pattern to get or initialize the MongoClient instance
///
/**
* @var MongoClient The mongo client to the database the collection is hosted
*/
public static $mongoClient = null;
/**
* Gets the existing MongoClient instance, or if not available, initializes one.
*
* @return MongoClient The MongoClient instance
*/
public static function getMongoClient () {
if (self::$mongoClient === null) {
self::$mongoClient = self::initializeMongoClient();
}
return self::$mongoClient;
}
///
/// Mongo objects initialization and helper methods
///
/**
* Gets the MongoDB connection string
*
* @return string The connection string
*/
private static function getConnectionString () {
global $Config;
//Protocol
$connectionString = 'mongodb://';
//Host
if (isset($Config['DocumentStorage']) && array_key_exists('Host', $Config['DocumentStorage'])) {
$connectionString .= $Config['DocumentStorage']['Host'];
} else {
$connectionString .= MONGO_DEFAULT_HOST;
}
//Port
$connectionString .= ':';
if (isset($Config['DocumentStorage']) && array_key_exists('Port', $Config['DocumentStorage'])) {
$connectionString .= $Config['DocumentStorage']['Port'];
} else {
$connectionString .= MONGO_DEFAULT_PORT;
}
return $connectionString;
}
/**
* Initializes a new MongoClient instance
*
* @return MongoClient the client
*/
public static function initializeMongoClient () {
global $Config;
$connectionString = self::getConnectionString();
if (isset($Config['DocumentStorage']) && array_key_exists('SSL', $Config['DocumentStorage'])) {
$context = stream_context_create(
[ 'ssl' => $Config['DocumentStorage']['SSL'] ]
);
$m = new MongoClient(
$connectionString,
[ 'ssl' => true ],
[ 'context' => $context ]
);
} else {
$m = new MongoClient($connectionString);
}
return $m;
}
/**
* Gets the database to use for the current collection
*/
public static function getDatabase () {
global $Config;
if (isset($Config['DocumentStorage']) && array_key_exists('Database', $Config['DocumentStorage'])) {
return $Config['DocumentStorage']['Database'];
}
return MONGO_DEFAULT_DATABASE;
}
///
/// Constructor
///
/**
* Initializes a new instance of MongoCollection
*
* @param string $id the collection identifiant
*/
public function __construct ($id) {
$this->id = $id;
$m = self::getMongoClient();
$this->mongoCollection = $m->selectCollection(self::getDatabase(), $id);
}
///
/// Mongo BSON
///
/**
* Gets an associative array with document collection properties as key and values.
*
* @param CollectionDocument $document The document
* @return array The array representation of the document
*/
public function getArrayFromDocument (CollectionDocument $document) {
foreach ($document as $key => $value) {
if ($key == 'id') {
if ($value !== '') {
$array['_id'] = $value;
}
} else {
$array[$key] = $value;
}
}
return $array;
}
///
/// CRUD features
///
/**
* Adds a document to the collection
*
* @param CollectionDocument $document The document to add
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function add (CollectionDocument &$document) {
$object = static::getArrayFromDocument($document);
$this->mongoCollection->save($object);
$document->id = $object['_id'];
}
/**
* Deletes a document from the collection
*
* @param string $documentId The identifiant of the document to delete
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function delete ($documentId) {
$this->mongoCollection->remove(
[ '_id' => $documentId ]
);
}
/**
* Determines if a document exists
*
* @param CollectionDocument $document The document to check
* @return boolean true if the document exists; otherwise, false.
*/
public function exists (CollectionDocument $document) {
//According https://blog.serverdensity.com/checking-if-a-document-exists-mongodb-slow-findone-vs-find/
//this is more efficient to use find than findOne() to determine existence.
$cursor = $this->mongoCollection->find(
[ '_id' => $document->id ]
)->limit(1);
return $cursor->hasNext();
}
/**
* Updates a document in the collection
*
* @param CollectionDocument $document The document to update
* @return boolean true if the operation succeeded; otherwise, false.
*/
public function update (CollectionDocument &$document) {
$object = static::getArrayFromDocument($document);;
$this->mongoCollection->update(
[ '_id' => $document->id ],
$object
);
}
/**
* Gets a document from the collection
*
* @param string $documentId The identifiant of the document to get
* @param CollectionDocument $document The document
*/
public function get ($documentId) {
$data = $this->mongoCollection->findOne(
[ '_id' => $documentId ]
);
+ return $this->getDocumentFromArray($data);
+ }
+
+ /**
+ * Gets a document of the relevant collection documents type from an array.
+ */
+ public function getDocumentFromArray($documentArray) {
$type = $this->documentType;
if (!class_exists($type)) {
- throw new Exception("Can't create an instance of $type. If the class exists, did you registered a SPL autoloader or updated includes/autoload.php?");
+ throw new Exception("Can't create an instance of $type. If the class exists, did you register a SPL autoloader or updated includes/autoload.php?");
}
- return $type::loadFromObject($data);
+ return $type::loadFromObject($documentArray);
+ }
+
+ /**
+ * Gets a count of the documents in the collection
+ *
+ * @return int The number of documents
+ */
+ public function count () {
+ return $this->mongoCollection->count();
+ }
+
+ /**
+ * Gets all the documents from the collection
+ *
+ * @return Iterator An iterator to the documents, each item an instance of CollectionDocument
+ */
+ public function getAll () {
+ return new MongoDBCollectionIterator($this);
}
}
diff --git a/includes/collection/MongoDBCollectionIterator.php b/includes/collection/MongoDBCollectionIterator.php
new file mode 100644
index 0000000..715bc78
--- /dev/null
+++ b/includes/collection/MongoDBCollectionIterator.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * _, __, _, _ __, _ _, _, _
+ * / \ |_) (_ | | \ | /_\ |\ |
+ * \ / |_) , ) | |_/ | | | | \|
+ * ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+ *
+ * MongoDB colletction iterator class
+ *
+ * @package ObsidianWorkspaces
+ * @subpackage Collection
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @filesource
+ */
+
+/**
+ * Iterator for MongoDBCollection::getAll()
+ */
+class MongoDBCollectionIterator implements Iterator {
+ /**
+ * @var MongoCursor The MongoDB cursor
+ */
+ private $cursor;
+
+ /**
+ * @var MongoDBCollection The collection attached to the current iterator instance
+ */
+ private $collection;
+
+ /**
+ * Initializes a new instance of the MongoDBCollectionIterator object
+ *
+ * @param MongoDBCollection $collection The collection to itrate
+ * @param MongoCursor $cursor The cursor to the results [optional]
+ */
+ public function __construct (MongoDBCollection $collection, MongoCursor $cursor = null) {
+ $this->collection = $collection;
+ if ($cursor === null) {
+ $this->cursor = $collection->mongoCollection->find();
+ } else {
+ $this->cursor = $cursor;
+ }
+ }
+
+ /**
+ * Returns the current element
+ */
+ public function current () {
+ return $this->collection->getDocumentFromArray($this->cursor->current());
+ }
+
+ /**
+ * Returns the key of the current element
+ */
+ public function key () {
+ return $this->cursor->key();
+ }
+
+ /**
+ * Moves forward to next element
+ */
+ public function next () {
+ $this->cursor->next();
+ }
+
+ /**
+ * Rewinds the iterator to the first element
+ */
+ public function rewind () {
+ $this->cursor->rewind();
+ }
+
+ /**
+ * Checks if current position is valid
+ */
+ public function valid () {
+ return $this->cursor->valid();
+ }
+}
diff --git a/tests/collections/CRUDTestTrait.php b/tests/collections/CRUDTestTrait.php
index 3a40677..6320d6d 100644
--- a/tests/collections/CRUDTestTrait.php
+++ b/tests/collections/CRUDTestTrait.php
@@ -1,156 +1,221 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* CRUD features tests for each Collection class.
*
* @package ObsidianWorkspaces
* @subpackage Tests
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
require_once('../includes/autoload.php');
/**
* A CollectionDocument class, for our tests.
*/
class BookDocument extends CollectionDocument {
/**
* @var string The book title
*/
public $title;
/**
* @var string The book author
*/
public $author;
/**
* Initializes a new instance of the BookDocument object
*/
public function __construct ($author = null, $title = null) {
if ($title !== null) $this->title = $title;
if ($author !== null) $this->author = $author;
}
}
/**
* The tests for our basic, non storage engine specific CRUD features
*
* For coverage purposes, it requires a coversDefaultClass annotation in the classes using this trait.
*/
trait CRUDTestTrait {
/**
* @var BookDocument The document to test every CRUD feature
*/
protected $redBook;
/**
* @var BookDocument A second document to test Set in two scenarii
*/
protected $blueBook;
/**
* Initializes two documents for the tests
*/
public function initializeDocuments() {
$this->blueBook = new BookDocument('Isaac Asimov', 'Foundation');
$this->redBook = new BookDocument('Iain Banks', 'Matter'); //M. will be added in update test
$this->redBook->id = 'redBook';
}
/**
* @covers ::add
* @covers ::exists
* @covers ::update
* @covers ::get
* @covers ::set
* @covers ::delete
+ * @covers ::count
+ * @covers ::getAll
*/
public function testCRUD () {
global $Config;
$Config = static::getConfig();
- //Add
+ //::count
+ $this->assertEquals(
+ 0, $this->collection->count(),
+ "The test collection isn't empty. Check the last test run cleaned correctly the resources."
+ );
+
+ //::add
$this->collection->add($this->redBook);
$this->assertNotEmpty(
$this->redBook->id,
"After a document has been added, the is has been deleted."
);
$this->assertEquals(
'redBook',
$this->redBook->id,
"After a document has been added, the is has been modified."
);
- //Exists
+ //:ccount
+ $this->assertEquals(1, $this->collection->count());
+
+ //::exists
$this->assertFalse(
$this->collection->exists($this->blueBook),
"A non added document has been marked existing."
);
$this->assertTrue(
$this->collection->exists($this->redBook),
"An added document hasn't been found as existing."
);
- //Update
+ //::update
$this->redBook->author = 'Iain M. Banks';
$this->collection->update($this->redBook);
$this->assertEquals(
'redBook',
$this->redBook->id,
"The document ID has been modified during an update operation. It should stay the same. Old id: redBook. New id: " . $this->redBook->id
);
- //Get - wwen our collection uses the generic CollectionDocument class
+ //::count
+ $this->assertEquals(1, $this->collection->count()
+ );
+
+ //::get - when our collection uses the generic CollectionDocument class
$newDocument = $this->collection->get($this->redBook->id);
$this->assertInstanceOf('CollectionDocument', $newDocument);
$this->assertNotInstanceOf('BookDocument', $newDocument);
- //Get - when our collection uses a proper CollectionDocument descendant
+ //::set - when our collection uses a proper CollectionDocument descendant
$this->collection->documentType = 'BookDocument';
$newBook = $this->collection->get($this->redBook->id);
$this->assertInstanceOf('BookDocument', $newBook);
$this->assertObjectHasAttribute('title', $newBook);
$this->assertObjectHasAttribute('author', $newBook);
$this->assertObjectHasAttribute('id', $newBook);
$this->assertEquals('Matter', $newBook->title);
$this->assertEquals('Iain M. Banks', $newBook->author);
$this->assertEquals('redBook', $newBook->id);
- //Set
+ //::set - an existing document as parameter
$previousId = $this->redBook->id;
$this->collection->set($this->redBook);
$this->assertEquals(
$previousId,
$this->redBook->id,
"The document ID has been modified during a set operation on an already added dcoument. It should stay the same. Old id: $previousId. New id: " . $this->redBook->id
);
- $this->collection->add($this->blueBook);
+
+ //::count
+ $this->assertEquals(1, $this->collection->count());
+
+ //::set - a new document as parameter
+ $this->collection->set($this->blueBook);
$this->assertNotEmpty(
$this->blueBook->id,
"After a document has been added, the expected behavior is the id property is filled with the generated identifiant."
);
$this->assertTrue(
$this->collection->exists($this->blueBook),
"An added document with set hasn't been found as existing."
);
+ //::count
+ $this->assertEquals(2, $this->collection->count());
+
+ //::getAll
+ $documents = $this->collection->getAll();
+ $count = 0;
+ foreach ($documents as $document) {
+ switch ($document->id) {
+ case $this->blueBook->id:
+ $this->assertInstanceOf('BookDocument', $document);
+ $this->assertObjectHasAttribute('title', $document);
+ $this->assertObjectHasAttribute('author', $document);
+ $this->assertObjectHasAttribute('id', $document);
+ $this->assertEquals('Foundation', $document->title);
+ $this->assertEquals('Isaac Asimov', $document->author);
+ break;
+
+ case 'redBook':
+ $this->assertInstanceOf('BookDocument', $document);
+ $this->assertObjectHasAttribute('title', $document);
+ $this->assertObjectHasAttribute('author', $document);
+ $this->assertObjectHasAttribute('id', $document);
+ $this->assertEquals('Matter', $document->title);
+ $this->assertEquals('Iain M. Banks', $document->author);
+ break;
+
+ default:
+ $this->fail('A document with an id nor redBook, the blueBook generated id has been returned.');
+ }
+ $count++;
+ }
+ $this->assertEquals(2, $count);
+
+ //::delete
$this->collection->delete($this->blueBook->id);
$this->assertFalse(
$this->collection->exists($this->blueBook),
"A deleted document has been marked existing."
);
$this->assertTrue(
$this->collection->exists($this->redBook),
"An unexpected document has been deleted."
);
+
+ //::count
+ $this->assertEquals(1, $this->collection->count());
+
+ //::delete, ::count
+ $this->collection->delete($this->redBook->id);
+ $this->assertEquals(0, $this->collection->count());
+
+ //::getAll
+ $documents = $this->collection->getAll();
+ $this->assertCount(0, $documents, "We expected each collection document would have been deleted.");
}
}
diff --git a/tests/collections/FilesCollectionTest.php b/tests/collections/FilesCollectionTest.php
index 2388c92..9be68b0 100644
--- a/tests/collections/FilesCollectionTest.php
+++ b/tests/collections/FilesCollectionTest.php
@@ -1,186 +1,188 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Unit testing — FilesCollection class
*
* @package ObsidianWorkspaces
* @subpackage Tests
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
require_once('CRUDTestTrait.php');
+require('../includes/GlobalFunctions.php');
/**
* Tests FilesCollection class
* @coversDefaultClass FilesCollection
*/
class FilesCollectionTest extends PHPUnit_Framework_TestCase {
/**
* @var string Our collection
*/
protected $collection;
/**
* Gets default configuration for this test
*
* @return array The configuration block
*/
protected static function getConfig () {
return [
'DocumentStorage' => [
'Type' => 'Files',
'Path' => '/tmp/obsidiancollections'
]
];
}
/**
* Initializes a new instance of the PHPUnit_Framework_TestCase class
*
* @param string $name The test case name
*/
public function __construct (string $name = null) {
parent::__construct($name);
$this->initializeDocuments();
global $Config;
$Config = self::getConfig();
$this->collection = new FilesCollection('quux');
}
///
/// Specific tests for this particular Collection class
///
/**
* @covers FilesCollection::__construct
*/
public function testConstructor () {
global $Config;
$Config = self::getConfig();
$collection = new FilesCollection('quux');
$this->assertEquals('quux', $collection->id);
}
/**
* @covers FilesCollection::getCollectionPath
* @covers FilesCollection::getDocumentPath
*/
public function testPaths () {
global $Config;
$Config = self::getConfig();
$this->assertEquals(
'/tmp/obsidiancollections/quux',
FilesCollection::getCollectionPath('quux')
);
$this->assertFileExists(
'/tmp/obsidiancollections/quux'
);
$this->assertEquals(
'/tmp/obsidiancollections/quux/foo.json',
$this->collection->getDocumentPath('foo')
);
}
/**
* @covers FilesCollection::getCollectionPath
*/
public function testConfigurationMissingException () {
//Note: @expectedException isn't allowed in PHPUnit to test the generic Exception class.
global $Config;
$oldConfigDocumentStorage = $Config['DocumentStorage'];
$Config['DocumentStorage'] = []; //Path isn't defined
try {
FilesCollection::getCollectionPath('quux');
} catch (Exception $ex) {
$Config['DocumentStorage'] = $oldConfigDocumentStorage;
return;
}
$this->fail('An expected exception has not been raised.');
}
/**
* @covers FilesCollection::getCollectionPath
*/
public function testCantCreateDirectoryException () {
//Note: @expectedException isn't allowed in PHPUnit to test the generic Exception class.
global $Config;
$oldConfigDocumentStorage = $Config['DocumentStorage'];
$Config['DocumentStorage'] = [
'Type' => 'Files',
'Path' => '/root/obsidiancollections',
];
try {
FilesCollection::getCollectionPath('quux');
} catch (Exception $ex) {
$Config['DocumentStorage'] = $oldConfigDocumentStorage;
return;
}
$this->fail("An expected exception has not been raised. If you're logged as root, you can safely delete /root/obsidiancollections folder and ignore this test. By the way, are you sure to trust a tests sequence creating and deleting files to run them as root?");
}
///
/// CRUD tests
///
use CRUDTestTrait;
/**
* @covers FilesCollection::add
* @covers FilesCollection::update
*/
public function testFileContent () {
global $Config;
$Config = self::getConfig();
$book = new BookDocument('Iain Banks', 'Excession');
$book->id = 'greenBook';
$this->collection->add($book);
$filename = $this->collection->getDocumentPath('greenBook');
$this->assertJsonFileEqualsJsonFile(
'collections/greenBook1.json',
$filename
);
$book->author = 'Iain M. Banks';
$this->collection->update($book);
$this->assertJsonFileEqualsJsonFile(
'collections/greenBook2.json',
$filename
);
+
+ //Cleans up, so CRUD test starts with an empty collection
+ unlink('/tmp/obsidiancollections/quux/greenBook.json');
}
///
/// Cleanup
///
/**
* Tears down resources when tests are done
*/
public static function tearDownAfterClass () {
- //Removes created files and directories
- unlink('/tmp/obsidiancollections/quux/greenBook.json');
- unlink('/tmp/obsidiancollections/quux/redBook.json');
+ //Removes created directories
rmdir('/tmp/obsidiancollections/quux');
rmdir('/tmp/obsidiancollections');}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Sep 18, 11:43 (17 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2990697
Default Alt Text
(41 KB)

Event Timeline