Skip to content

Simplified foundational classes for Model, View and Controller. #1120

Merged
merged 3 commits into from Apr 17, 2012
Jump to file
+2,032 −0
View
69 docs/manual/en-US/chapters/classes/jcontrollerbase.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JControllerBase</title>
+
+ <section>
+ <title>Construction</title>
+
+ <para>The constructor for <classname>JControllerBase</classname> takes an optional <classname>JInput</classname> object and an
+ optional <classname>JApplciationBase</classname> object. If either is omitted, the constructor defers to the protected
+ loadInput and loadApplication methods respectively. These methods can be overriden in derived classes if the default
+ application and request input is not appropriate.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>The <classname>JControllerBase</classname> class is abstract so cannot be used directly. The derived class must
+ implement the execute method to satisfy the interface requirements. Note that the execute method no longer takes a "task"
+ argument as each controller class. Multi-task controllers are still possible but not recommended. Each controller class should
+ do just one sort of 'thing', just as saving, deleting, checking in, checking out and so on. However, controllers, or even
+ models and views, have the liberty of invoking other controllers to allow for HMVC architectures.</para>
+
+ <example>
+ <title>Example controller</title>
+
+ <programlisting> /**
+ * My custom controller.
+ *
+ * @package Examples
+ *
+ * @since 12.1
+ */
+class MyController extends JControllerBase
+{
+ /**
+ * Method to execute the controller.
+ *
+ * @return void
+ *
+ * @since 12.1
+ * @throws RuntimeException
+ */
+ public function execute()
+ {
+ echo time();
+ }
+}
+
+// Instantiate the controller.
+$controller = new MyController;
+
+// Print the time.
+$controller-&gt;execute();</programlisting>
+ </example>
+ </section>
+
+ <section>
+ <title>Serialization</title>
+
+ <para>The <classname>JControllerBase</classname> class implements <interfacename>Serializable</interfacename>. When
+ serializing, only the input property is serialized. When unserializing, the input variable is unserialized and the internal
+ application property is loaded at runtime.</para>
+ </section>
+</section>
View
51 docs/manual/en-US/chapters/classes/jmodelbase.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JModelBase</title>
+
+ <section>
+ <title>Construction</title>
+
+ <para>The contructor for <classname>JModelBase</classname> takes an optional <classname>JRegistry</classname> object that
+ defines the state of the model. If omitted, the contructor defers to the protected <methodname>loadState</methodname> method.
+ This method can be overriden in a derived class and takes the place of the <methodname>populateState</methodname> method used
+ in the legacy model class.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>The <classname>JModelBase</classname> class is abstract so cannot be used directly. All requirements of the interface
+ are already satisfied by the base class.</para>
+
+ <example>
+ <title>Example model</title>
+
+ <programlisting> /**
+ * My custom model.
+ *
+ * @pacakge Examples
+ *
+ * @since 12.1
+ */
+class MyModel extends JModelBase
+{
+ /**
+ * Get the time.
+ *
+ * @return integer
+ *
+ * @since 12.1
+ */
+ public function getTime()
+ {
+ return time();
+ }
+}</programlisting>
+ </example>
+ </section>
+</section>
View
73 docs/manual/en-US/chapters/classes/jmodeldatabase.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JModelDatabase</title>
+
+ <section>
+ <title>Construction</title>
+
+ <para><classname>JModelDatabase</classname> is extended from <classname>JModelBase</classname> and the contructor takes an
+ optional <classname>JDatabaseDriver</classname> object and an optional <classname>JRegistry</classname> object (the same one
+ that <classname>JModelBase</classname> uses). If the database object is omitted, the contructor defers to the protected
+ <methodname>loadDb</methodname> method which loads the database object from the platform factory.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>The <classname>JModelDatabase</classname> class is abstract so cannot be used directly. It forms a base for any model
+ that needs to interact with a database.</para>
+
+ <example>
+ <title>Example database model</title>
+
+ <programlisting> /**
+ * My custom database model.
+ *
+ * @package Examples
+ *
+ * @since 12.1
+ */
+class MyDatabaseModel extends JModelDatabase
+{
+ /**
+ * Get the content count.
+ *
+ * @return integer
+ *
+ * @since 12.1
+ * @throws RuntimeException on database error.
+ */
+ public function getCount()
+ {
+ // Get the query builder from the internal database object.
+ $q = $this-&gt;db-&gt;getQuery(true);
+
+ // Prepare the query to count the number of content records.
+ $q-&gt;select('COUNT(*)')
+ -&gt;from($q-&gt;qn('#__content'));
+
+ $this-&gt;db-&gt;setQuery($q);
+
+ // Execute and return the result.
+ return $this-&gt;db-&gt;loadResult();
+ }
+}
+
+try
+{
+ $model = new MyDatabaseModel;
+ $count = $model-&gt;getCount();
+}
+catch (RuntimeException $e)
+{
+ // Handle database error.
+}
+</programlisting>
+ </example>
+ </section>
+</section>
View
75 docs/manual/en-US/chapters/classes/jviewbase.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JViewBase</title>
+
+ <section>
+ <title>Construction</title>
+
+ <para>The contructor for <classname>JViewBase</classname> takes a <classname>JModel</classname> object and a
+ <classname>JController</classname> object. Both are mandatory.</para>
+
+ <para>Note that these are interfaces so the objects do no necessarily have to extend from <classname>JModelBase</classname> or
+ <classname>JControllerBase</classname> classes. Given that, the view should only rely on the API that is exposed by the
+ interface and not concrete classes unless the contructor is changed in a derived class to take more explicit classes or
+ interaces as required by the developer.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>The <classname>JViewBase</classname> class is abstract so cannot be used directly. It forms a simple base for rendering
+ any kind of data. The class already implements the <methodname>escape</methodname> method so only a
+ <methodname>render</methodname> method need to be added. Views derived from this class would be used to support very simple
+ cases, well suited to supporting web services returning JSON, XML or possibly binary data types. This class does not support
+ layouts.</para>
+
+ <example>
+ <title>Example view</title>
+
+ <programlisting> /**
+ * My custom view.
+ *
+ * @package Examples
+ *
+ * @since 12.1
+ */
+class MyView extends JViewBase
+{
+ /**
+ * Render some data
+ *
+ * @return string The rendered view.
+ *
+ * @since 12.1
+ * @throws RuntimeException on database error.
+ */
+ public function render()
+ {
+ // Prepare some data from the model.
+ $data = array(
+ 'count' =&gt; $this-&gt;model-&gt;getCount()
+ );
+
+ // Convert the data to JSON format.
+ return json_encode($data);
+ }
+}
+
+try
+{
+ $view = new MyView(new MyDatabaseModel, new MyController);
+ echo $view-&gt;render();
+}
+catch (RuntimeException $e)
+{
+ // Handle database error.
+}
+</programlisting>
+ </example>
+ </section>
+</section>
View
83 docs/manual/en-US/chapters/classes/jviewhtml.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JViewHtml</title>
+
+ <section>
+ <title>Construction</title>
+
+ <para><classname>JViewHtml</classname> is extended from <classname>JViewBase</classname>. The constructor, in addition to the
+ model and controller arguments, take an optional <classname>SplPriorityQueue</classname> object that serves as a lookup for
+ layouts. If omitted, the view defers to the protected <methodname>loadPaths</methodname> method.</para>
+ </section>
+
+ <section>
+ <title>Usage</title>
+
+ <para>The <classname>JViewHtml</classname> class is abstract so cannot be used directly. This view class implements render. It
+ will try to find the layout, include it using output buffering and return the result. The following examples show a layout
+ file that is assumed to be stored in a generic layout folder not stored under the web-server root.</para>
+
+ <example>
+ <title>Example HTML layout</title>
+
+ <programlisting>&lt;?php
+/**
+ * Example layout "layouts/count.php".
+ *
+ * @package Examples
+ * @since 12.1
+ */
+
+// Declare variables to support type hinting.
+
+/** @var $this MyHtmlView */
+?&gt;
+
+&lt;dl&gt;
+ &lt;dt&gt;Count&lt;/dt&gt;
+ &lt;dd&gt;&lt;?php echo $this-&gt;model-&gt;getCount(); ?&gt;&lt;/dd&gt;
+&lt;/dl&gt;</programlisting>
+ </example>
+
+ <example>
+ <title>Example HTML view</title>
+
+ <programlisting> /**
+ * My custom HTML view.
+ *
+ * @package Examples
+ * @since 12.1
+ */
+class MyHtmlView extends JViewHtml
+{
+ /**
+ * Redefine the model so the correct type hinting is available in the layout.
+ *
+ * @var MyDatabaseModel
+ * @since 12.1
+ */
+ protected $model;
+}
+
+try
+{
+ $paths = new SplPriorityQueue;
+ $paths-&gt;insert(__DIR__ . '/layouts');
@elinw
elinw added a note Apr 11, 2012

When I tried this I got a warning saying that insert() requires two parameters.

@robschley
robschley added a note Apr 12, 2012

Elin, you're right. It is missing the priority. Not sure how this got missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ $view = new MyView(new MyDatabaseModel, new MyController, $paths);
@elinw
elinw added a note Apr 11, 2012

Should this (MyView) match the name of the class?

Also this does not match the signature for JViewHtml is that is what it is supposed to be ... that takes only two arguments and the second own should be the splPriorityQueue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $view-&gt;setLayout('count');
+ echo $view-&gt;render();
+}
+catch (RuntimeException $e)
+{
+ // Handle database error.
+}
+</programlisting>
+ </example>
+ </section>
+</section>
View
13 docs/manual/en-US/chapters/interfaces/jcontroller.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JController</title>
+
+ <para><interfacename>JController</interfacename> is an interface that requires a class to be implemented with an
+ <methodname>execute</methodname>, a <methodname>getApplication</methodname> and a <methodname>getInput</methodname>
+ method.</para>
+</section>
View
12 docs/manual/en-US/chapters/interfaces/jmodel.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JModel</title>
+
+ <para><interfacename>JModel</interfacename> is an interface that requires a class to be implemented with a
+ <methodname>getState</methodname> and a <methodname>setState</methodname> method.</para>
+</section>
View
12 docs/manual/en-US/chapters/interfaces/jview.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section>
+ <title>JView</title>
+
+ <para><interfacename>JView</interfacename> is an interface that requires a class to be implemented with an
+ <methodname>escape</methodname> and a <methodname>render</methodname> method.</para>
+</section>
View
2 docs/manual/en-US/chapters/packages.xml
@@ -16,5 +16,7 @@
<xi:include href="packages/log.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="packages/database.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="packages/mvc.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</chapter>
View
57 docs/manual/en-US/chapters/packages/mvc.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "../../Developer_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<section id="chap-Joomla_Platform_Manual-MVC">
+ <title>The Model-View-Controller Packages</title>
+
+ <section>
+ <title>Introduction</title>
+
+ <para>Version 12.1 of the platform introduced a new format for model-view-controller paradigm. Principly, the classes
+ <classname>JModel</classname>, <classname>JView</classname> and <classname>JController</classname> are now interfaces and the
+ base abstract classes are now <classname>JModelBase</classname>, <classname>JViewBase</classname> and
+ <classname>JControllerBase</classname> respectively. In additional, all classes have been simplified removing a lot of
+ coupling with the Joomla CMS that is unnecessary for standalone Joomla Platform applications.</para>
+
+ <para>All the API for controllers, models and views has moved from the Application package into separate Controller, Model and
+ View packages respectively. Much of the API previously devoted to adding include paths for each of the classes has been
+ removed because of improvements in the auto-loader or by registering or discovering classes explicitly using
+ <classname>JLoader</classname>.</para>
+
+ <para>Controllers only support one executable task per class via the execute method. This differs from the legacy
+ <classname>JController</classname> class which mapped tasks to methods in a single class. Messages and redirection are not
+ always required so have been dropped in this base class. They can be provided in a downstream class to suit individual
+ applications. Likewise, methods to create models and views have been dropped in favor of using application or package factory
+ classes.</para>
+
+ <para>Models have been greatly simplified in comparison to their legacy counterpart. The base model is nothing more than a
+ class to hold state. All database support methods have been dropped except for database object support in
+ <classname>JModelDatabase</classname>. Extended model classes such as <classname>JModelAdmin</classname>,
+ <classname>JModelForm</classname>, <classname>JModelItem</classname> and <classname>JModelList</classname> are part of the
+ legacy platform. Most of their function has been replaced by API availble in the Content package also new in 12.1.</para>
+
+ <para>Views have also been greatly simplified. Views are now injected with a single model and a controller. Magic get methods
+ have been dropped in favor of using the model directly. Similarly, assignment methods have also been dropped in favor of
+ setting class properties explicitly. The <classname>JViewHtml</classname> class still implements layout support albeit in a
+ simplified manner.</para>
+ </section>
+
+ <xi:include href="../interfaces/jcontroller.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../classes/jcontrollerbase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../interfaces/jmodel.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../classes/jmodelbase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../classes/jmodeldatabase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../interfaces/jview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../classes/jviewbase.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="../classes/jviewhtml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+</section>
View
137 libraries/joomla/controller/base.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Controller
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform Base Controller Class
+ *
+ * @package Joomla.Platform
+ * @subpackage Controller
+ * @since 12.1
+ */
+abstract class JControllerBase implements JController
+{
+ /**
+ * The application object.
+ *
+ * @var JApplicationBase
+ * @since 12.1
+ */
+ protected $app;
+
+ /**
+ * The input object.
+ *
+ * @var JInput
+ * @since 12.1
+ */
+ protected $input;
+
+ /**
+ * Instantiate the controller.
+ *
+ * @param JInput $input The input object.
+ * @param JApplicationBase $app The application object.
+ *
+ * @since 12.1
+ */
+ public function __construct(JInput $input = null, JApplicationBase $app = null)
+ {
+ // Setup dependencies.
+ $this->app = isset($app) ? $app : $this->loadApplication();
+ $this->input = isset($input) ? $input : $this->loadInput();
+ }
+
+ /**
+ * Get the application object.
+ *
+ * @return JApplicationBase The application object.
+ *
+ * @since 12.1
+ */
+ public function getApplication()
+ {
+ return $this->app;
+ }
+
+ /**
+ * Get the input object.
+ *
+ * @return JInput The input object.
+ *
+ * @since 12.1
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Serialize the controller.
+ *
+ * @return string The serialized controller.
+ *
+ * @since 12.1
+ */
+ public function serialize()
+ {
+ return serialize($this->input);
+ }
+
+ /**
+ * Unserialize the controller.
+ *
+ * @param string $input The serialized controller.
+ *
+ * @return JController Supports chaining.
+ *
+ * @since 12.1
+ * @throws UnexpectedValueException if input is not the right class.
+ */
+ public function unserialize($input)
+ {
+ // Setup dependencies.
+ $this->app = $this->loadApplication();
+
+ // Unserialize the input.
+ $this->input = unserialize($input);
+
+ if (!($this->input instanceof JInput))
+ {
+ throw new UnexpectedValueException(sprintf('%s::unserialize would not accept a `%s`.', get_class($this), gettype($this->input)));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Load the application object.
+ *
+ * @return JApplicationBase The application object.
+ *
+ * @since 12.1
+ */
+ protected function loadApplication()
+ {
+ return JFactory::getApplication();
+ }
+
+ /**
+ * Load the input object.
+ *
+ * @return JInput The input object.
+ *
+ * @since 12.1
+ */
+ protected function loadInput()
+ {
+ return $this->app->input;
+ }
+}
View
51 libraries/joomla/controller/controller.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Controller
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform Controller Interface
+ *
+ * @package Joomla.Platform
+ * @subpackage Controller
+ * @since 12.1
+ */
+interface JController extends Serializable
+{
+ /**
+ * Execute the controller.
+ *
+ * @return boolean True if controller finished execution, false if the controller did not
+ * finish execution. A controller might return false if some precondition for
+ * the controller to run has not been satisfied.
+ *
+ * @since 12.1
+ * @throws LogicException
+ * @throws RuntimeException
+ */
+ public function execute();
+
+ /**
+ * Get the application object.
+ *
+ * @return JApplicationBase The application object.
+ *
+ * @since 12.1
+ */
+ public function getApplication();
+
+ /**
+ * Get the input object.
+ *
+ * @return JInput The input object.
+ *
+ * @since 12.1
+ */
+ public function getInput();
+}
View
79 libraries/joomla/model/base.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform Base Model Class
+ *
+ * @package Joomla.Platform
+ * @subpackage Model
+ * @since 12.1
+ */
+abstract class JModelBase implements JModel
+{
+ /**
+ * The model state.
+ *
+ * @var JRegistry
+ * @since 12.1
+ */
+ protected $state;
+
+ /**
+ * Instantiate the model.
+ *
+ * @param JRegistry $state The model state.
+ *
+ * @since 12.1
+ */
+ public function __construct(JRegistry $state = null)
+ {
+ // Setup the model.
+ $this->state = isset($state) ? $state : $this->loadState();
+ }
+
+ /**
+ * Get the model state.
+ *
+ * @return JRegistry The state object.
+ *
+ * @since 12.1
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ /**
+ * Set the model state.
+ *
+ * @param JRegistry $state The state object.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setState(JRegistry $state)
+ {
+ $this->state = $state;
+ }
+
+ /**
+ * Load the model state.
+ *
+ * @return JRegistry The state object.
+ *
+ * @since 12.1
+ */
+ protected function loadState()
+ {
+ return new JRegistry;
+ }
+}
View
82 libraries/joomla/model/database.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform Database Model Class
+ *
+ * @package Joomla.Platform
+ * @subpackage Model
+ * @since 12.1
+ */
+abstract class JModelDatabase extends JModelBase
+{
+ /**
+ * The database driver.
+ *
+ * @var JDatabaseDriver
+ * @since 12.1
+ */
+ protected $db;
+
+ /**
+ * Instantiate the model.
+ *
+ * @param JRegistry $state The model state.
+ * @param JDatabaseDriver $db The database adpater.
+ *
+ * @since 12.1
+ */
+ public function __construct(JRegistry $state = null, JDatabaseDriver $db = null)
+ {
+ parent::__construct($state);
+
+ // Setup the model.
+ $this->db = isset($db) ? $db : $this->loadDb();
+ }
+
+ /**
+ * Get the database driver.
+ *
+ * @return JDatabaseDriver The database driver.
+ *
+ * @since 12.1
+ */
+ public function getDb()
+ {
+ return $this->db;
+ }
+
+ /**
+ * Set the database driver.
+ *
+ * @param JDatabaseDriver $db The database driver.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setDb(JDatabaseDriver $db)
+ {
+ $this->db = $db;
+ }
+
+ /**
+ * Load the database driver.
+ *
+ * @return JDatabaseDriver The database driver.
+ *
+ * @since 12.1
+ */
+ protected function loadDb()
+ {
+ return JFactory::getDbo();
+ }
+}
View
40 libraries/joomla/model/model.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform Model Interface
+ *
+ * @package Joomla.Platform
+ * @subpackage Model
+ * @since 12.1
+ */
+interface JModel
+{
+ /**
+ * Get the model state.
+ *
+ * @return JRegistry The state object.
+ *
+ * @since 12.1
+ */
+ public function getState();
+
+ /**
+ * Set the model state.
+ *
+ * @param JRegistry $state The state object.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setState(JRegistry $state);
+}
View
56 libraries/joomla/view/base.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform Base View Class
+ *
+ * @package Joomla.Platform
+ * @subpackage View
+ * @since 12.1
+ */
+abstract class JViewBase implements JView
+{
+ /**
+ * The model object.
+ *
+ * @var JModel
+ * @since 12.1
+ */
+ protected $model;
+
+ /**
+ * Method to instantiate the view.
+ *
+ * @param JModel $model The model object.
+ *
+ * @since 12.1
+ */
+ public function __construct(JModel $model)
+ {
+ // Setup dependencies.
+ $this->model = $model;
+ }
+
+ /**
+ * Method to escape output.
+ *
+ * @param string $output The output to escape.
+ *
+ * @return string The escaped output.
+ *
+ * @see JView::escape()
+ * @since 12.1
+ */
+ public function escape($output)
+ {
+ return $output;
+ }
+}
View
185 libraries/joomla/view/html.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+jimport('joomla.filesystem.path');
+
+/**
+ * Joomla Platform HTML View Class
+ *
+ * @package Joomla.Platform
+ * @subpackage View
+ * @since 12.1
+ */
+abstract class JViewHtml extends JViewBase
+{
+ /**
+ * The view layout.
+ *
+ * @var string
+ * @since 12.1
+ */
+ protected $layout = 'default';
+
+ /**
+ * The paths queue.
+ *
+ * @var SplPriorityQueue
+ * @since 12.1
+ */
+ protected $paths;
+
+ /**
+ * Method to instantiate the view.
+ *
+ * @param JModel $model The model object.
+ * @param SplPriorityQueue $paths The paths queue.
+ *
+ * @since 12.1
+ */
+ public function __construct(JModel $model, SplPriorityQueue $paths = null)
+ {
+ parent::__construct($model);
+
+ // Setup dependencies.
+ $this->paths = isset($paths) ? $paths : $this->loadPaths();
+ }
+
+ /**
+ * Method to escape output.
+ *
+ * @param string $output The output to escape.
+ *
+ * @return string The escaped output.
+ *
+ * @see JView::escape()
+ * @since 12.1
+ */
+ public function escape($output)
+ {
+ // Escape the output.
+ return htmlspecialchars($output, ENT_COMPAT, 'UTF-8');
+ }
+
+ /**
+ * Method to get the view layout.
+ *
+ * @return string The layout name.
+ *
+ * @since 12.1
+ */
+ public function getLayout()
+ {
+ return $this->layout;
+ }
+
+ /**
+ * Method to get the layout path.
+ *
+ * @param string $layout The layout name.
+ *
+ * @return mixed The layout file name if found, false otherwise.
+ *
+ * @since 12.1
+ */
+ public function getPath($layout)
+ {
+ // Get the layout file name.
+ $file = JPath::clean($layout . '.php');
+
+ // Find the layout file path.
+ $path = JPath::find(clone($this->paths), $file);
+
+ return $path;
+ }
+
+ /**
+ * Method to get the view paths.
+ *
+ * @return SplPriorityQueue The paths queue.
+ *
+ * @since 12.1
+ */
+ public function getPaths()
+ {
+ return $this->paths;
+ }
+
+ /**
+ * Method to render the view.
+ *
+ * @return string The rendered view.
+ *
+ * @since 12.1
+ * @throws RuntimeException
+ */
+ public function render()
+ {
+ // Get the layout path.
+ $path = $this->getPath($this->getLayout());
+
+ // Check if the layout path was found.
+ if (!$path)
+ {
+ throw new RuntimeException('Layout Path Not Found');
+ }
+
+ // Start an output buffer.
+ ob_start();
+
+ // Load the layout.
+ include $path;
+
+ // Get the layout contents.
+ $output = ob_get_clean();
+
+ return $output;
+ }
+
+ /**
+ * Method to set the view layout.
+ *
+ * @param string $layout The layout name.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setLayout($layout)
+ {
+ $this->layout = $layout;
+ }
+
+ /**
+ * Method to set the view paths.
+ *
+ * @param SplPriorityQueue $paths The paths queue.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ public function setPaths(SplPriorityQueue $paths)
+ {
+ $this->paths = $paths;
+ }
+
+ /**
+ * Method to load the paths queue.
+ *
+ * @return SplPriorityQueue The paths queue.
+ *
+ * @since 12.1
+ */
+ protected function loadPaths()
+ {
+ return new SplPriorityQueue;
+ }
+}
View
41 libraries/joomla/view/view.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * @package Joomla.Platform
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+defined('JPATH_PLATFORM') or die;
+
+/**
+ * Joomla Platform View Interface
+ *
+ * @package Joomla.Platform
+ * @subpackage View
+ * @since 12.1
+ */
+interface JView
+{
+ /**
+ * Method to escape output.
+ *
+ * @param string $output The output to escape.
+ *
+ * @return string The escaped output.
+ *
+ * @since 12.1
+ */
+ public function escape($output);
+
+ /**
+ * Method to render the view.
+ *
+ * @return string The rendered view.
+ *
+ * @since 12.1
+ * @throws RuntimeException
+ */
+ public function render();
+}
View
54 tests/core/mock/controller.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @package Joomla.Test
+ *
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+/**
+ * Class to mock JController.
+ *
+ * @package Joomla.Test
+ * @since 12.1
+ */
+class TestMockController
+{
+ /**
+ * Creates and instance of the mock JController object.
+ *
+ * @param object $test A test object.
+ *
+ * @return object
+ *
+ * @since 12.1
+ */
+ public static function create($test)
+ {
+ // Collect all the relevant methods in JController.
+ $methods = array(
+ 'execute',
+ 'getApplication',
+ 'getInput',
+ 'serialize',
+ 'unserialize',
+ );
+
+ // Create the mock.
+ $mockObject = $test->getMock(
+ 'JControllerBase',
+ $methods,
+ // Constructor arguments.
+ array(),
+ // Mock class name.
+ '',
+ // Call original constructor.
+ false
+ );
+
+ // TODO Mock the input.
+ TestReflection::setValue($mockObject, 'input', new JInput);
+
+ return $mockObject;
+ }
+}
View
186 tests/suites/unit/joomla/controller/JControllerBaseTest.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage Controller
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+JLoader::register('BaseController', __DIR__ . '/stubs/tbase.php');
+
+/**
+ * Tests for the JController class.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage Controller
+ * @since 12.1
+ */
+class JControllerBaseTest extends TestCase
+{
+ /**
+ * @var JControllerBase
+ * @since 12.1
+ */
+ private $_instance;
+
+ /**
+ * Tests the __construct method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::__construct
+ * @since 12.1
+ */
+ public function test__construct()
+ {
+ // New controller with no dependancies.
+ $this->assertEquals('default', TestReflection::getValue($this->_instance, 'app')->input, 'Checks the mock application came from the factory.');
+ $this->assertAttributeEquals('default', 'input', $this->_instance, 'Checks the input came from the application.');
+
+ // New controller with dependancies
+ $app = TestMockApplicationWeb::create($this);
+ $app->test = 'ok';
+
+ $class = new BaseController(new JInputCookie, $app);
+ $this->assertAttributeInstanceOf('JInputCookie', 'input', $class, 'Checks the type of the injected input.');
+ $this->assertAttributeSame($app, 'app', $class, 'Checks the injected application.');
+ }
+
+ /**
+ * Tests the getApplication method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::getApplication
+ * @since 12.1
+ */
+ public function testGetApplication()
+ {
+ TestReflection::setValue($this->_instance, 'app', 'application');
+ $this->assertEquals('application', $this->_instance->getApplication());
+ }
+
+ /**
+ * Tests the getInput method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::getInput
+ * @since 12.1
+ */
+ public function testGetInput()
+ {
+ TestReflection::setValue($this->_instance, 'input', 'input');
+ $this->assertEquals('input', $this->_instance->getInput());
+ }
+
+ /**
+ * Tests the serialize method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::serialize
+ * @since 12.1
+ */
+ public function testSerialise()
+ {
+ $this->assertEquals('s:7:"default";', $this->_instance->serialize());
+ }
+
+ /**
+ * Tests the unserialize method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::unserialize
+ * @since 12.1
+ */
+ public function testUnserialise()
+ {
+ $input = serialize(new JInput);
+
+ $this->assertSame($this->_instance, $this->_instance->unserialize($input), 'Checks chaining and target method.');
+ $this->assertInstanceOf('JInput', $this->_instance->getInput());
+ }
+
+ /**
+ * Tests the unserialize method for an expected exception.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::unserialize
+ * @since 12.1
+ *
+ * @expectedException UnexpectedValueException
+ */
+ public function testUnserialise_exception()
+ {
+ $this->_instance->unserialize('s:7:"default";');
+ }
+
+ /**
+ * Tests the loadApplication method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::loadApplication
+ * @since 12.1
+ */
+ public function testLoadApplication()
+ {
+ JFactory::$application = 'application';
+ $this->assertEquals('application', TestReflection::invoke($this->_instance, 'loadApplication'));
+ }
+
+ /**
+ * Tests the loadInput method.
+ *
+ * @return void
+ *
+ * @covers JControllerBase::loadInput
+ * @since 12.1
+ */
+ public function testLoadInput()
+ {
+ // Reset the input property so we know it changes based on the mock application.
+ TestReflection::setValue($this->_instance, 'input', null);
+
+ $this->assertEquals('default', TestReflection::invoke($this->_instance, 'loadInput'));
+ }
+
+ /**
+ * Setup the tests.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->saveFactoryState();
+
+ $app = TestMockApplicationWeb::create($this);
+ $app->input = 'default';
+
+ JFactory::$application = $app;
+
+ $this->_instance = new BaseController;
+ }
+
+ /**
+ * Method to tear down whatever was set up before the test.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function tearDown()
+ {
+ $this->restoreFactoryState();
+
+ parent::teardown();
+ }
+}
View
31 tests/suites/unit/joomla/controller/stubs/tbase.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage Controller
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+/**
+ * Concrete class extending JControllerBase.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage Controller
+ * @since 12.1
+ */
+class BaseController extends JControllerBase
+{
+ /**
+ * Method to execute the controller.
+ *
+ * @return void
+ *
+ * @since 12.1
+ * @throws RuntimeException
+ */
+ public function execute()
+ {
+ return 'base';
+ }
+}
View
101 tests/suites/unit/joomla/model/JModelBaseTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+JLoader::register('BaseModel', __DIR__ . '/stubs/tbase.php');
+
+/**
+ * Tests for the JViewBase class.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage Mapper
+ * @since 12.1
+ */
+class JModelBaseTest extends TestCase
+{
+ /**
+ * @var BaseModel
+ * @since 12.1
+ */
+ private $_instance;
+
+ /**
+ * Tests the __construct method.
+ *
+ * @return void
+ *
+ * @covers JModelBase::__construct
+ * @since 12.1
+ */
+ public function test__construct()
+ {
+ $this->assertEquals(new JRegistry, $this->_instance->getState(), 'Checks default state.');
+
+ $state = new JRegistry(array('foo' => 'bar'));
+ $class = new BaseModel($state);
+ $this->assertEquals($state, $class->getState(), 'Checks state injection.');
+ }
+
+ /**
+ * Tests the getState method.
+ *
+ * @return void
+ *
+ * @covers JModelBase::getState
+ * @since 12.1
+ */
+ public function testGetState()
+ {
+ // Reset the state property to a known value.
+ TestReflection::setValue($this->_instance, 'state', 'foo');
+
+ $this->assertEquals('foo', $this->_instance->getState());
+ }
+
+ /**
+ * Tests the setState method.
+ *
+ * @return void
+ *
+ * @covers JModelBase::setState
+ * @since 12.1
+ */
+ public function testSetState()
+ {
+ $state = new JRegistry(array('foo' => 'bar'));
+ $this->_instance->setState($state);
+ $this->assertSame($state, $this->_instance->getState());
+ }
+
+ /**
+ * Tests the loadState method.
+ *
+ * @return void
+ *
+ * @covers JModelBase::loadState
+ * @since 12.1
+ */
+ public function testLoadState()
+ {
+ $this->assertInstanceOf('JRegistry', TestReflection::invoke($this->_instance, 'loadState'));
+ }
+
+ /**
+ * Setup the tests.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->_instance = new BaseModel;
+ }
+}
View
122 tests/suites/unit/joomla/model/JModelDatabaseTest.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+JLoader::register('DatabaseModel', __DIR__ . '/stubs/tdatabase.php');
+
+/**
+ * Tests for the JViewBase class.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage Mapper
+ * @since 12.1
+ */
+class JModelDatabaseTest extends TestCase
+{
+ /**
+ * @var DatabaseModel
+ * @since 12.1
+ */
+ private $_instance;
+
+ /**
+ * Tests the __construct method.
+ *
+ * @return void
+ *
+ * @covers JModelDatabase::__construct
+ * @since 12.1
+ */
+ public function test__construct()
+ {
+ $this->assertSame(JFactory::getDbo(), $this->_instance->getDb(), 'Checks default database driver.');
+
+ // Create a new datbase mock for injection.
+ $db = TestMockDatabaseDriver::create($this);
+ $class = new DatabaseModel(null, $db);
+ $this->assertSame($db, $class->getDb(), 'Checks injected database driver.');
+ }
+
+ /**
+ * Tests the getDb method.
+ *
+ * @return void
+ *
+ * @covers JModelDatabase::getDb
+ * @since 12.1
+ */
+ public function testGetDb()
+ {
+ // Reset the db property to a known value.
+ TestReflection::setValue($this->_instance, 'db', 'foo');
+
+ $this->assertEquals('foo', $this->_instance->getDb());
+ }
+
+ /**
+ * Tests the setDb method.
+ *
+ * @return void
+ *
+ * @covers JModelDatabase::setDb
+ * @since 12.1
+ */
+ public function testSetDb()
+ {
+ $db = TestMockDatabaseDriver::create($this);
+ $this->_instance->setDb($db);
+
+ $this->assertAttributeSame($db, 'db', $this->_instance);
+ }
+
+ /**
+ * Tests the loadDb method.
+ *
+ * @return void
+ *
+ * @covers JModelDatabase::loadDb
+ * @since 12.1
+ */
+ public function testLoadDb()
+ {
+ JFactory::$database = 'database';
+ $this->assertEquals('database', TestReflection::invoke($this->_instance, 'loadDb'));
+ }
+
+ /**
+ * Setup the tests.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->saveFactoryState();
+
+ JFactory::$database = TestMockDatabaseDriver::create($this);
+
+ $this->_instance = new DatabaseModel;
+ }
+
+ /**
+ * Method to tear down whatever was set up before the test.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function tearDown()
+ {
+ $this->restoreFactoryState();
+
+ parent::teardown();
+ }
+}
View
19 tests/suites/unit/joomla/model/stubs/tbase.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+/**
+ * Concrete class extending JModelBase.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage Model
+ * @since 12.1
+ */
+class BaseModel extends JModelBase
+{
+}
View
19 tests/suites/unit/joomla/model/stubs/tdatabase.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage Model
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+/**
+ * Concrete class extending JModelDatabase.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage Model
+ * @since 12.1
+ */
+class DatabaseModel extends JModelDatabase
+{
+}
View
69 tests/suites/unit/joomla/view/JViewBaseTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+JLoader::register('BaseView', __DIR__ . '/stubs/tbase.php');
+JLoader::register('JModelMock', __DIR__ . '/mocks/JModelMock.php');
+
+/**
+ * Tests for the JViewBase class.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage View
+ * @since 12.1
+ */
+class JViewBaseTest extends TestCase
+{
+ /**
+ * @var JViewBase
+ * @since 12.1
+ */
+ private $_instance;
+
+ /**
+ * Tests the __construct method.
+ *
+ * @return void
+ *
+ * @covers JViewBase::__construct
+ * @since 12.1
+ */
+ public function test__construct()
+ {
+ $this->assertAttributeInstanceOf('JModel', 'model', $this->_instance);
+ }
+
+ /**
+ * Tests the escape method.
+ *
+ * @return void
+ *
+ * @covers JViewBase::escape
+ * @since 12.1
+ */
+ public function testEscape()
+ {
+ $this->assertEquals('foo', $this->_instance->escape('foo'));
+ }
+
+ /**
+ * Setup the tests.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $model = JModelMock::create($this);
+
+ $this->_instance = new BaseView($model);
+ }
+}
View
211 tests/suites/unit/joomla/view/JViewHtmlTest.php
@@ -0,0 +1,211 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+JLoader::register('HtmlView', __DIR__ . '/stubs/thtml.php');
+JLoader::register('JModelMock', __DIR__ . '/mocks/JModelMock.php');
+
+/**
+ * Tests for the JViewHtml class.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage View
+ * @since 12.1
+ */
+class JViewHtmlTest extends TestCase
+{
+ /**
+ * @var JViewHtml
+ * @since 12.1
+ */
+ private $_instance;
+
+ /**
+ * Tests the __construct method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::__construct
+ * @since 12.1
+ */
+ public function test__construct()
+ {
+ $this->assertAttributeEquals(new SplPriorityQueue, 'paths', $this->_instance, 'Check default paths.');
+
+ $model = JModelMock::create($this);
+ $paths = new SplPriorityQueue;
+ $paths->insert('foo', 1);
+
+ $this->_instance = new HtmlView($model, $paths);
+ $this->assertAttributeSame($paths, 'paths', $this->_instance, 'Check default paths.');
+ }
+
+ /**
+ * Tests the escape method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::escape
+ * @since 12.1
+ */
+ public function testEscape()
+ {
+ $this->assertEquals('&quot;', $this->_instance->escape('"'));
+ }
+
+ /**
+ * Tests the getLayout method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::getLayout
+ * @since 12.1
+ */
+ public function testGetLayout()
+ {
+ TestReflection::setValue($this->_instance, 'layout', 'foo');
+
+ $this->assertEquals('foo', $this->_instance->getLayout());
+ }
+
+ /**
+ * Tests the getPath method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::getPath
+ * @since 12.1
+ */
+ public function testGetPath()
+ {
+ // Set up a priority queue.
+ $paths = $this->_instance->getPaths();
+ $paths->insert(__DIR__ . '/layouts1', 1);
+ $paths->insert(__DIR__ . '/layouts2', 2);
+
+ $this->assertEquals(__DIR__ . '/layouts2/olivia.php', $this->_instance->getPath('olivia'));
+ $this->assertEquals(__DIR__ . '/layouts1/peter.php', $this->_instance->getPath('peter'));
+ $this->assertEquals(__DIR__ . '/layouts2/fauxlivia.php', $this->_instance->getPath('fauxlivia'));
+ $this->assertEquals(__DIR__ . '/layouts1/fringe/division.php', $this->_instance->getPath('fringe/division'));
+ $this->assertFalse($this->_instance->getPath('walter'));
+
+ // Check dirty path.
+ $this->assertEquals(__DIR__ . '/layouts1/fringe/division.php', $this->_instance->getPath('fringe//\\division'));
+ }
+
+ /**
+ * Tests the getPaths method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::getPaths
+ * @since 12.1
+ */
+ public function testGetPaths()
+ {
+ // Inject a known value into the property.
+ TestReflection::setValue($this->_instance, 'paths', 'paths');
+
+ // Check dirty path.
+ $this->assertEquals('paths', $this->_instance->getPaths());
+ }
+
+ /**
+ * Tests the render method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::render
+ * @since 12.1
+ */
+ public function testRender()
+ {
+ // Set up a priority queue.
+ $paths = $this->_instance->getPaths();
+ $paths->insert(__DIR__ . '/layouts1', 1);
+ $paths->insert(__DIR__ . '/layouts2', 2);
+
+ $this->_instance->setLayout('olivia');
+ $this->assertEquals('Peter\'s Olivia', $this->_instance->render());
+ }
+
+ /**
+ * Tests the render method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::render
+ * @since 12.1
+ *
+ * @expectedException RuntimeException
+ */
+ public function testRender_exception()
+ {
+ $this->_instance->render();
+ }
+
+ /**
+ * Tests the setLayout method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::setLayout
+ * @since 12.1
+ */
+ public function testSetLayout()
+ {
+ $this->_instance->setLayout('fringe/division');
+ $this->assertAttributeSame('fringe/division', 'layout', $this->_instance);
+ }
+
+ /**
+ * Tests the setPaths method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::setPaths
+ * @since 12.1
+ */
+ public function testSetPaths()
+ {
+ $paths = new SplPriorityQueue;
+ $paths->insert('bar', 99);
+
+ $this->_instance->setPaths($paths);
+ $this->assertAttributeSame($paths, 'paths', $this->_instance);
+ }
+
+ /**
+ * Tests the loadPaths method.
+ *
+ * @return void
+ *
+ * @covers JViewHtml::loadPaths
+ * @since 12.1
+ */
+ public function testLoadPaths()
+ {
+ $this->assertEquals(new SplPriorityQueue, TestReflection::invoke($this->_instance, 'loadPaths'));
+ }
+
+ /**
+ * Setup the tests.
+ *
+ * @return void
+ *
+ * @since 12.1
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $model = JModelMock::create($this);
+
+ $this->_instance = new HtmlView($model);
+ }
+}
View
1 tests/suites/unit/joomla/view/layouts1/fringe/division.php
@@ -0,0 +1 @@
+Fringe Division
View
1 tests/suites/unit/joomla/view/layouts1/olivia.php
@@ -0,0 +1 @@
+Olivia Dunham
View
1 tests/suites/unit/joomla/view/layouts1/peter.php
@@ -0,0 +1 @@
+Peter Bishop
View
1 tests/suites/unit/joomla/view/layouts2/fauxlivia.php
@@ -0,0 +1 @@
+Olivia Dunham (red hair)
View
1 tests/suites/unit/joomla/view/layouts2/olivia.php
@@ -0,0 +1 @@
+Peter's Olivia
View
48 tests/suites/unit/joomla/view/mocks/JModelMock.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @copyright Copyright (C) 2005 - 2012 Open Source Matters. All rights reserved.
+ * @license GNU General Public License
+ */
+
+/**
+ * Mock class for JModel.
+ *
+ * @package Joomla.UnitTest
+ * @since 12.1
+ */
+class JModelMock
+{
+ /**
+ * Creates and instance of the mock JModel object.
+ *
+ * @param object $test A test object.
+ *
+ * @return object
+ *
+ * @since 12.1
+ */
+ public static function create($test)
+ {
+ // Collect all the relevant methods in JModel.
+ $methods = array(
+ 'getState',
+ 'loadState',
+ 'setState',
+ );
+
+ // Create the mock.
+ $mockObject = $test->getMock(
+ 'JModel',
+ $methods,
+ // Constructor arguments.
+ array(),
+ // Mock class name.
+ '',
+ // Call original constructor.
+ false
+ );
+
+ return $mockObject;
+ }
+}
View
30 tests/suites/unit/joomla/view/stubs/tbase.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+/**
+ * Concrete class extending JViewBase.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage View
+ * @since 12.1
+ */
+class BaseView extends JViewBase
+{
+ /**
+ * Method to render the view.
+ *
+ * @return string The rendered view.
+ *
+ * @since 12.1
+ * @throws RuntimeException
+ */
+ public function render()
+ {
+ }
+}
View
19 tests/suites/unit/joomla/view/stubs/thtml.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @package Joomla.UnitTest
+ * @subpackage View
+ *
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE
+ */
+
+/**
+ * Concrete class extending JViewHtml.
+ *
+ * @package Joomla.UnitTest
+ * @subpackage View
+ * @since 12.1
+ */
+class HtmlView extends JViewHtml
+{
+}
Something went wrong with that request. Please try again.