diff options
28 files changed, 8 insertions, 1166 deletions
diff --git a/.gitattributes b/.gitattributes index d97b8693..e05638c0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1468,29 +1468,6 @@ demos/time-tracker/protected/App_Data/TimeTrackerUserTypeHandler.php -text  demos/time-tracker/protected/App_Data/mysql4-sqlmap.xml -text  demos/time-tracker/protected/App_Data/sqlite-sqlmap.xml -text  demos/time-tracker/protected/application.xml -text -demos/time-tracker/protected/pages/Docs/CreateBusinessCode.page -text -demos/time-tracker/protected/pages/Docs/DatabaseDesign.page -text -demos/time-tracker/protected/pages/Docs/GettingStarted.page -text -demos/time-tracker/protected/pages/Docs/Home.page -text -demos/time-tracker/protected/pages/Docs/Introduction.page -text -demos/time-tracker/protected/pages/Docs/Layout.php -text -demos/time-tracker/protected/pages/Docs/Layout.tpl -text -demos/time-tracker/protected/pages/Docs/MoreTests.page -text -demos/time-tracker/protected/pages/Docs/TopicList.php -text -demos/time-tracker/protected/pages/Docs/TopicList.tpl -text -demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page -text -demos/time-tracker/protected/pages/Docs/UsingSQLMap.page -text -demos/time-tracker/protected/pages/Docs/WritingFunctionalTest.page -text -demos/time-tracker/protected/pages/Docs/WritingUnitTest.page -text -demos/time-tracker/protected/pages/Docs/config.xml -text -demos/time-tracker/protected/pages/Docs/db.png -text -demos/time-tracker/protected/pages/Docs/functional_test1.png -text -demos/time-tracker/protected/pages/Docs/functional_test2.png -text -demos/time-tracker/protected/pages/Docs/preface.page -text -demos/time-tracker/protected/pages/Docs/project1.png -text -demos/time-tracker/protected/pages/Docs/unit_test1.png -text -demos/time-tracker/protected/pages/Docs/unit_test2.png -text -demos/time-tracker/protected/pages/Docs/unit_test3.png -text  demos/time-tracker/protected/pages/TimeTracker/CategoryDataList.php -text  demos/time-tracker/protected/pages/TimeTracker/CategoryDataList.tpl -text  demos/time-tracker/protected/pages/TimeTracker/LogTimeEntry.page -text diff --git a/demos/time-tracker/index.php b/demos/time-tracker/index.php index 9a03ed65..7954aeb9 100644 --- a/demos/time-tracker/index.php +++ b/demos/time-tracker/index.php @@ -6,7 +6,8 @@ $frameworkPath='../../framework/prado.php';  $assetsPath=$basePath."/assets";
  $runtimePath=$basePath."/protected/runtime";
 -$sqliteDbDir = $basePath."/protected/App_Data/SQLite";
 +$sqlite_dir = $basePath."/protected/App_Data/SQLite";
 +$sqlite_db = $sqlite_dir.'/time-tracker.db';
  if(!is_file($frameworkPath))
  	die("Unable to find prado framework path $frameworkPath.");
 @@ -14,8 +15,10 @@ if(!is_writable($assetsPath))  	die("Please make sure that the directory $assetsPath is writable by Web server process.");
  if(!is_writable($runtimePath))
  	die("Please make sure that the directory $runtimePath is writable by Web server process.");
 -if(!is_writable($sqliteDbDir))
 -	die("Please make sure that the directory $sqliteDbDir is writable by Web server process.");
 +if(!is_writable($sqlite_dir))
 +	die("Please make sure that the directory $sqlite_dir is writable by Web server process.");
 +if(!is_writable($sqlite_db))
 +	die("Please make sure that the sqlite database file $sqlite_dir is writable by Web server process.");
  require_once($frameworkPath);
 diff --git a/demos/time-tracker/protected/application.xml b/demos/time-tracker/protected/application.xml index d9e4d01c..bae5f126 100644 --- a/demos/time-tracker/protected/application.xml +++ b/demos/time-tracker/protected/application.xml @@ -17,7 +17,7 @@  	<module id="cache" class="System.Caching.TMemCache" />
  -->
  	<module id="daos" class="DaoManager" EnableCache="true"
 -  		configFile="Application.App_Data.mysql4-sqlmap">
 +  		configFile="Application.App_Data.sqlite-sqlmap">
  		<dao id="UserDao" class="Application.App_Code.Dao.UserDao" />
  		<dao id="ProjectDao" class="Application.App_Code.Dao.ProjectDao" />
  		<dao id="TimeEntryDao" class="Application.App_Code.Dao.TimeEntryDao" />
 diff --git a/demos/time-tracker/protected/pages/Docs/CreateBusinessCode.page b/demos/time-tracker/protected/pages/Docs/CreateBusinessCode.page deleted file mode 100644 index e5afa572..00000000 --- a/demos/time-tracker/protected/pages/Docs/CreateBusinessCode.page +++ /dev/null @@ -1,127 +0,0 @@ -<com:TContent ID="body">
 -<h1>Create Business Code</h1>
 -<p>We start the design with the database, the entity relationships are shown
 -in the diagram below.</p>
 -
 -<img src=<%~ db.png %> class="figure" />
 -
 -<p>Now we can begin to create and test some business code. Let us begin
 -with the <tt>Project</tt> defintions. First, we add some properties or fields.</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -<?php
 -class Project
 -{
 -	 public $ActualDuration = 0;
 -	 public $CreatorUserName = '';
 -	 public $CompletionDate = 0;
 -	 public $DateCreated = 0;
 -	 public $Description = '';
 -	 public $EstimateDuration = 0;
 -	 public $ID = 0;
 -	 public $ManagerUserName = '';
 -	 public $Name = '';
 -}
 -?>
 -</com:TTextHighlighter>
 -
 -<p>All the fields should be self explainatory. The <tt>ManagerUserName</tt>
 -is the user name of the project manager. Notice that the fields
 -are public, later on, we can change some or all of them to be private and
 -provide some accessor and mutators (i.e. getters and setters). If we want
 -we can let the <tt>Project</tt> class inherit <tt>TComponent</tt> such
 -that the getters and setters can be used like properties, such as those
 -found in Prado.</p>
 -
 -<h2>Business Services, test case first</h2>
 -<p>Next we want to add users to the project. For this, we start with some
 -unit tests. We are going to design the business logic around the concept of 
 -<a href="java">Data Access Objects</a> (DAO).</p> 
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -<?php
 -Prado::using('Application.APP_CODE.*');
 -class ProjectDaoTestCase extends UnitTestCase
 -{
 -	function testProjectDaoCanCreateNewProject()
 -	{
 -		$project = new Project();
 -		$project->Name = "Project 1";
 -		
 -		$dao = new ProjectDao();
 -		
 -		$this->assertTrue($dao->createNewProject($project));
 -		$this->assertEqual($dao->getProjectByID(1), $project);
 -	}
 -}
 -?>
 -</com:TTextHighlighter>
 -<p>So what are we doing here? First we create a new <tt>Project</tt> named
 -"Project 1". Then we create a new <tt>ProjectDao</tt> so we can insert new projects
 -and retrieve it. We assert that a project will be create sucessfully using
 -<tt>assertTrue($do->createNewProject(...))</tt>. We also assert that
 -<tt>getProjectByID(1)</tt> will return an instance of <tt>Project</tt> class
 -with same data (the reference may be different).</p>
 -
 -<p>If we run the above unit test case, nothing is going to pass since we have
 -not even defined the <tt>ProjectDao</tt> class. So lets do that first and import
 -the class in the tests as well.</p>
 -
 -<p>We will create a base Dao class as follows, and we save as <tt>BaseDao.php</tt>
 -in our <tt>APP_CODE</tt> directory.</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -<?php
 -class BaseDao
 -{
 -	private $_connection;
 -	
 -	public function setConnection($connection)
 -	{
 -		$this->_connection = $connection;
 -	}
 -	
 -	protected function getConnection()
 -	{
 -		return $this->_connection;
 -	}
 -}
 -?>
 -</com:TTextHighlighter>
 -<p>And finally our <tt>ProjectDao</tt> class.</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -<?php
 -Prado::using('Application.APP_CODE.BaseDao');
 -class ProjectDao extends BaseDao
 -{
 -}
 -?>
 -</com:TTextHighlighter>
 -<p>If we run the unit test again, we get an error message something like
 -"<i>Fatal error: Call to undefined method ProjectDao::createNewProject() in ...</i>".
 -So let us, fix this.
 -</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -class ProjectDao extends BaseDao
 -{
 -	public function createNewProject($project)
 -	{		
 -	} 
 -	
 -	public function getProjectByID($projectID)
 -	{	
 -	}
 -}
 -</com:TTextHighlighter>
 -<p>Run the unit test again, we see a different type of error now. This time
 -the unit test runner complians that the test fails.</p>
 -<h2>Write Test, Run Test, Repeat</h2>
 -<div class="info">
 -<b>At this point, you may notice a repetition</b>
 -<ol>
 -	<li>write some test code,</li>
 -	<li>run the test, test gives an error,</li>
 -	<li>write some actual code to only remove the previous error,</li>
 -	<li>goto step 1 to repeat.</li>
 -</ol>
 -</div>
 -<p>We shall see how we can make this test pass in the next section.</p>
 -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/DatabaseDesign.page b/demos/time-tracker/protected/pages/Docs/DatabaseDesign.page deleted file mode 100644 index a306ba2c..00000000 --- a/demos/time-tracker/protected/pages/Docs/DatabaseDesign.page +++ /dev/null @@ -1,42 +0,0 @@ -<com:TContent ID="body">
 -<h1>Database Design</h1>
 -<p>The design steps we take in the sample application is a data centric
 -approach. That is, we shall consider the application from the view
 -point of data structures, data relationships and data integrity.
 -Other designs starting from object and class design are also possible but is
 -not the approach taken in this guide.
 -</p>
 -
 -<h2>Entity Relationship</h2>
 -<p>We start with the following entity relationship diagram. 
 -The bold text in each entity indicate required fields. The underline
 -text indicates the entity's primary key, also denoted as <tt>PK</tt>.
 -Entity relationships are indicated with arrows between entities and
 -each relationship field is denoted with <tt>FK</tt>.</p>  
 -
 -<p>The four entities: <tt>Project</tt>, <tt>Categories</tt>, <tt>TimeEntry</tt> 
 -and <tt>ProjectMembers</tt>
 -makes up the time tracker application. While the other entities:
 -<tt>Users</tt>, <tt>UserRoles</tt>, <tt>RoleTypes</tt> and <tt>Signon</tt> are
 -usually found in applications where membership or user management is required.</p> 
 -
 -<img src=<%~ db.png %> class="figure" />
 -</p>
 -
 -<div class="info"><b>Info:</b>
 -See <a href="http://en.wikipedia.org/wiki/Database_normalization">Database Normalization</a>
 -for a quick reference regarding database design and normalization, especially the
 -3rd normal form (3NF).
 -</div>
 -
 -<h2>MySQL database</h2>
 -<p>We shall concentrate on the MySQL database for this sample application.
 -Other database engines are also possible and can be quite easily inter-changed.
 -The SQL script to initialize the MySQL database is given below. The following
 -SQL script was created using MySQL version 4.1.7. 
 -</p>
 -
 -<com:TTextHighlighter Language="sql" CssClass="source">
 -<%= file_get_contents('protected/data/time-tracker-mysql.sql') %>
 -</com:TTextHighlighter>
 -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/GettingStarted.page b/demos/time-tracker/protected/pages/Docs/GettingStarted.page deleted file mode 100644 index 8b8e8e5e..00000000 --- a/demos/time-tracker/protected/pages/Docs/GettingStarted.page +++ /dev/null @@ -1,67 +0,0 @@ -<com:TContent ID="body"> -<h1>Installation</h1> -<p>There are a few pieces of tools and software needed throughout the development  -of the application. First we shall setup the environment for coding and testing. We -shall from here on assume that you have access to a working installation of a web server with -PHP and possibilly a MySQL database server. The first thing to do is install Prado and some -testing tools.</p> - -<h2>Download and Install Prado</h2> -<p>The minimum requirement by PRADO is that the Web server support PHP 5.  -	For the Time Tracker sample application, you need Prado version 3.1 or greater.</p> -<p>Installation of PRADO mainly involves downloading and unpacking.</p> -<ol> -	<li>Go to <a href="http://www.pradosoft.com/download/">pradosoft.com</a> to grab the latest version of PRADO.</li> -	<li>Unpack the PRADO release file to a Web-accessible directory.</li> -</ol> - -<p>You should at least first check that the demos bundled with the Prado distribution are -	working. See the <a href="../quickstart/index.php?page=GettingStarted.Installation"> -		quickstart tutorial for further instructions</a> on running the demos. -</p> - -<h2>Help! Nothing is working!</h2> -<p>If you encounter problems in downloading, unpacking and running the demo applications, please -	visit the <a href="http://www.pradosoft.com/forum/">forum to seek help</a>. Please -	do a search on the forum first or <a href="http://www.pradosoft.com/demos/quickstart/prado3_quick_start.pdf">read the PDF version</a> of the quickstart.  -	The friendly and wonderful people at the forum can better assist you if you can provide as much detail regarding your problem.  -	You should include in your post your server configuration details, the steps you took to reproduce your problem, and any error messages encountered.</p> - -<h2>Create a new Prado application</h2> -<p>Prado is bundled with a command line tool to create the necessary directory structure to run a hello world application. -The command tool <tt>prado-cli.php</tt> is a php script and can be found in the <tt>prado/framework/</tt> directory. -To create a new application, go to your document root and type the following command in console. -</p> -<com:TTextHighlighter Language="none" CssClass="source"> -php prado/framework/prado-cli.php -t -c time-tracker -</com:TTextHighlighter> - -<div class="tip"><b class="tip">Tip:</b> -For linux and OS X environments, you can <tt>chmod u+x prado-cli.php</tt> -and change the first line of <tt>prado-cli.php</tt> to the location of your -PHP command line interpreter. Now, you may call the script from command line -like an executable. -</div> - -<p>A directory named <tt>time-tracker</tt> will be created containing the following. -<com:TTextHighlighter Language="none" CssClass="source"> -document_root/time-tracker/assets/ -document_root/time-tracker/index.php -document_root/time-tracker/protected/ -document_root/time-tracker/protected/.htaccess -document_root/time-tracker/protected/pages/ -document_root/time-tracker/protected/pages/Home.page -document_root/time-tracker/protected/runtime/ -</com:TTextHighlighter> -<p>The <tt>time-tracker</tt> directory is where we are going to put all our code for the Time Tracker application.  -Since <tt>-t</tt> was passed into the <tt>prado-cli.php</tt> script, unit and functional test -	skeletons are also created.</p> -<com:TTextHighlighter Language="none" CssClass="source"> -document_root/time-tracker/tests/ -document_root/time-tracker/tests/unit/ -document_root/time-tracker/tests/functional/ -document_root/time-tracker/tests/unit.php -document_root/time-tracker/tests/functional.php -</com:TTextHighlighter> - -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/Home.page b/demos/time-tracker/protected/pages/Docs/Home.page deleted file mode 100644 index 46876f26..00000000 --- a/demos/time-tracker/protected/pages/Docs/Home.page +++ /dev/null @@ -1,10 +0,0 @@ -<com:TContent ID="body"> -<h1>Prado Time Tracker Implementation Guide</h1> -<ul> -	<li><a href="?page=Docs.Introduction">Introduction</a></li> -	<li><a href="?page=Docs.GettingStarted">Getting Started</a></li> -	<li><a href="?page=Docs.WritingUnitTest">Writing a Unit Test</a></li> -	<li><a href="?page=Docs.WritingFunctionalTest">Writing a Functional Web Test</a></li> -	<li><a href="?page=Docs.CreateBusinessCode">Create Business Code</a></li> -</ul> -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/Introduction.page b/demos/time-tracker/protected/pages/Docs/Introduction.page deleted file mode 100644 index baa305f5..00000000 --- a/demos/time-tracker/protected/pages/Docs/Introduction.page +++ /dev/null @@ -1,64 +0,0 @@ -<com:TContent ID="body"> -<h1>Introduction</h1> - -<p>The Time Tracker is a fully functional sample application designed to  -	introduce you to many of Prado's features. This guide is a step by step -	walkthrough starting from installation to deployment. The Time Tracker -	application is based on the  -	<a href="http://www.asp.net/downloads/starterkits/">ASP.NET's Time Tracker Starter Kit</a>. -</p> - -<h1>Time Tracker Overview</h1> -<p>The Time Tracker is a business web application for keeping track of hours spent -on a project, with ability to handle multiple resources as well as multiple projects.</p> -<h2>Basic Application Requirements</h2> -<p>The functional requirements of the Time Tracker is based on the  -	<a href="http://www.asp.net/downloads/starterkits/">ASP.NET's Time Tracker Starter Kit</a>  -	description.</p> -<p class="requirements"> -<h3>Create projects</h3> -<ul> -	<li>Define projection information like due dates, hours to complete, project -		resources, and more.</li> -	<li>Break down projects into tasks and track work on per-task basis.</li> -</ul> -<h3>Create and track tasks</h3> -<ul> -	<li>Track time spent each day by category and project.</li> -</ul> -<h3>Use reports to track progress</h3> -<ul> -	<li>Track overall progress across multiple projects, including estimated and actual work.</li> -	<li>Track total work for team resources across multiple projects.</li> -</ul> -</p> - -<h2>Technologies and Design Approached Demonstrated</h2> -<ul> -	<li>Prado event-driven component framework</li> -	<li>Separation of concerns: persistent storage, business logic, presentation</li> -	<li>Object-Relational mapping using SQLMap</li> -	<li>Unit testing and functional testing</li> -	<li>Promote code reuse</li> -</ul> - -<h1>Requirements</h1> -<p>The Time Tracker web application requires the following software and knowledge.</p> -<h2>Software requirements</h2> -<p>It is assumed that you are able to obtain and install the following pieces of software.</p> -<ol> -	<li>PHP version 5.0.4 or greater</li> -	<li>A web server, such as Apache, able to run PHP scripts</li> -	<li>MySQL database server version 4.1 or greater (alternatively SQLite or Postgres)</li> -	<li>Prado version 3.1 or later</li>	 -</ol> - -<p>In addition to software requirements, we assumed that you have some of the following knowledge.</p> -<ul> -	<li>Access the internet to download packaged code, and unzip these code.</li> -	<li>Understand the basic concepts of Object-Oriented programming in PHP such as -		classes, objects, methods, etc.</li> -	<li>Basic understanding of relational databases and Structured Query Language (SQL).</li> -	<li>Knows how to have fun, this is mandatory.</li> -</ul> -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/Layout.php b/demos/time-tracker/protected/pages/Docs/Layout.php deleted file mode 100644 index e612d52d..00000000 --- a/demos/time-tracker/protected/pages/Docs/Layout.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php
 -
 -class Layout extends TTemplateControl
 -{
 -
 -}
 -?>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/Layout.tpl b/demos/time-tracker/protected/pages/Docs/Layout.tpl deleted file mode 100644 index 291c2482..00000000 --- a/demos/time-tracker/protected/pages/Docs/Layout.tpl +++ /dev/null @@ -1,45 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
 -
 -<com:THead Title="PRADO Time Tracker Guide">
 -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 -<meta http-equiv="content-language" content="en"/>
 -</com:THead>
 -
 -<body>
 -<com:TForm>
 -<div id="header">
 -<div class="title">PRADO Time Tracker Guide</div>
 -<div class="image"></div>
 -</div>
 -
 -<com:TPanel ID="MainMenu" CssClass="mainmenu">
 -<a href="?">Home</a> |
 -<a href="http://www.pradosoft.com">PradoSoft.com</a> |
 -<a href="../../docs/quickstart.pdf">PDF Version</a> |
 -<com:THyperLink ID="PrinterLink" Text="Printer-friendly Version" />
 -</com:TPanel>
 -
 -<table width="100%" border="0" cellspacing="0" cellpadding="0">
 -<tr>
 -<td valign="top" width="1">
 -<com:Application.pages.Docs.TopicList ID="TopicPanel" />
 -</td>
 -<td valign="top">
 -<div id="content">
 -<com:TContentPlaceHolder ID="body" />
 -</div>
 -</td>
 -</tr>
 -</table>
 -
 -<div id="footer">
 -Copyright © 2005-2006 <a href="http://www.pradosoft.com">PradoSoft</a>.
 -<br/><br/>
 -
 -<a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.0 Transitional</a>
 -</div>
 -
 -</com:TForm>
 -</body>
 -</html>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/MoreTests.page b/demos/time-tracker/protected/pages/Docs/MoreTests.page deleted file mode 100644 index 5e598982..00000000 --- a/demos/time-tracker/protected/pages/Docs/MoreTests.page +++ /dev/null @@ -1,140 +0,0 @@ -<com:TContent ID="body">
 -
 -<h1>Finishing up test case</h1>
 -<p>Up to this point, you should have the follow pieces of files and code.
 -<img src=<%~ project1.png %> class="figure" />
 -</p>
 -
 -<p>So what else can we test for at this point? A few reasonable
 -tests are to see what happens if the project already exists, and what if
 -the username does not exists.</p>
 -
 -<p>First we shall refactor our test code since much of the setup code 
 -for the mocked connection will need to be repeated in other test assertions.
 -We change the test case to have these three new methods.
 -</p>
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -function setupMockConnectionFor($project)
 -{
 -	$customer = new TimeTrackerUser();
 -	$customer->ID = 1;
 -	$customer->Name = "Customer A";
 -	
 -	$manager = new TimeTrackerUser();
 -	$manager->ID = 2;
 -	$manager->Name = "Manager A";
 -	
 -	$conn = $this->connection;
 -	
 -	//return the customer and manager
 -	$conn->setReturnValue('queryForObject', 
 -				$customer, array('GetUserByName', 'Customer A'));
 -	$conn->setReturnValue('queryForObject', 
 -				$manager, array('GetUserByName', 'Manager A'));
 -	
 -	//project does not exist
 -	$conn->setReturnValue('queryForObject', 
 -				null, array('GetProjectByName', 'Project 1'));
 -	
 -	$param['project'] = $project;
 -	$param['creator'] = $customer->ID;
 -	$param['manager'] = $manager->ID; 
 -			
 -	$conn->setReturnValue('insert', 
 -				true, array('CreateNewProject', $param));
 -	$conn->setReturnReference('queryForObject', 
 -				$project, array('GetProjectByID', 1));	
 -}
 -
 -function createNewTestProject()
 -{
 -	$project = new Project();
 -	$project->Name = "Project 1";
 -	$project->CreatorUserName = "Customer A";
 -	$project->ManagerUserName = "Manager A";
 -	
 -	return $project;
 -}
 -
 -function assertProjectCreated($project)
 -{
 -	$this->assertTrue($this->dao->createNewProject($project));		
 -	$this->assertEqual($this->dao->getProjectByID(1), $project);
 -}
 -</com:TTextHighlighter>
 -
 -<p>Our refactored test method <tt>testProjectDaoCanCreateNewProject()</tt> 
 -is as follows.</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -function testProjectDaoCanCreateNewProject()
 -{
 -	$project = $this->createNewTestProject();
 -
 -	if(($conn = $this->connection) instanceof MockTSqlMapper)
 -	{
 -		$this->setupMockConnectionFor($project);
 -		$conn->expectMinimumCallCount('queryForObject', 3);
 -		$conn->expectAtLeastOnce('insert');
 -	}
 -	
 -	$this->assertProjectCreated($project);	
 -}
 -</com:TTextHighlighter>
 -
 -<p>To test that the project already exists, we modify the mock
 -connection and test for an exception.</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -function testProjectExistsException()
 -{
 -	$project = $this->createNewTestProject();
 -	
 -	if(($conn = $this->connection) instanceof MockTSqlMapper)
 -	{
 -		//make the project exist
 -		$conn->setReturnValue('queryForObject', 
 -				$project, array('GetProjectByName', 'Project 1'));
 -		$this->setupMockConnectionFor($project);
 -	}
 -	
 -	try
 -	{
 -		$this->assertProjectCreated($project);		
 -		$this->fail();
 -	}
 -	catch(TimeTrackerException $e)
 -	{
 -		$this->pass();
 -	}
 -}
 -</com:TTextHighlighter>
 -
 -<p>Other test method for testing missing customer and manager users
 -are done similarly. At this point, the test case file looks quite large.
 -We shall not add more tests to this case and we should rename the file 
 -from <tt>ProjectDaoTestCase.php</tt> to <tt>CreateNewProjectTestCase.php</tt>.
 -
 -<div class="note"><b class="tip">Note:</b>
 -A heirachical exception class may be more useful in testing for specific
 -exceptions. For simplicity, we decided to use only <tt>TimeTrackerException</tt>
 -for this small project.
 -</div>
 -
 -<div class="tip"><b class="tip">Tip:</b>Class, method and file naming is very
 -important to any project, the name should inform you at first glance what
 -is to be expected from the class, method or file. In addition, the naming
 -scheme should be uniform over the project.
 -</div>
 -
 -<div class="info"><b class="tip">Comment:</b>
 -These test may be too ridget as any changes to the implementation may
 -actually cause the tests to fail. This is the case with grey-box/white-box
 -testing, you are actually testing the implementation. Black box tests may
 -be more preferable, as it should only test the class interface (the method or 
 -function details such as parameters and may be return values). However, 
 -with the use of database connection to retrive data within the objects under test,
 -it may be more suitable to do intergration tests.
 -</div>
 -
 -</com:TContent>
 -
 diff --git a/demos/time-tracker/protected/pages/Docs/TopicList.php b/demos/time-tracker/protected/pages/Docs/TopicList.php deleted file mode 100644 index ce827cc0..00000000 --- a/demos/time-tracker/protected/pages/Docs/TopicList.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php
 -
 -class TopicList extends TTemplateControl
 -{
 -
 -}
 -
 -?>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/TopicList.tpl b/demos/time-tracker/protected/pages/Docs/TopicList.tpl deleted file mode 100644 index 53243578..00000000 --- a/demos/time-tracker/protected/pages/Docs/TopicList.tpl +++ /dev/null @@ -1,27 +0,0 @@ -<div id="toc">
 -
 -<div class="topic">
 -<ul>
 -	<li><a href="?page=Docs.preface">Preface</a></li>
 -</ul>
 -<div>Prado Time Tracker Implementation Guide</div>
 -<ul>
 -	<li><a href="?page=Docs.Introduction">Introduction</a></li>
 -	<li><a href="?page=Docs.GettingStarted">Installation</a></li>
 -	<li><a href="?page=Docs.WritingUnitTest">Writing a Unit Test</a></li>
 -	<li><a href="?page=Docs.WritingFunctionalTest">Writing a Functional Web Test</a></li>
 -</ul>
 -
 -<div>Testing Business Code</div>
 -<ul>
 -	<li><a href="?page=Docs.DatabaseDesign">Database Design</a></li>
 -	<li><a href="?page=Docs.UsingSQLMap">Using SQLMap Data Mapper</a></li>
 -	<li><a href="?page=Docs.UserClassAndExceptions">User Class and Exceptions</a></li>
 -	<li><a href="?page=Docs.MoreTests">More Tests</a></li>
 -</ul>
 -
 -</div>
 -
 -
 -
 -</div>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page b/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page deleted file mode 100644 index f85e00be..00000000 --- a/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page +++ /dev/null @@ -1,202 +0,0 @@ -<com:TContent ID="body">
 -<h1>More complete ProjectTestCase</h1>
 -<p>
 -In creating a new project, we need to check the following:
 -<ul>
 -	<li>that the project does not already exists, i.e. no duplicate project name</li>
 -	<li>that the project creator and project manager exists when a new project is created</li>
 -</ul>
 -So to perform this task, we will modified the test code. 
 -<com:TTextHighlighter Language="php" CssClass="source">
 -function testProjectDaoCanCreateNewProject()
 -{
 -	$project = new Project();
 -	$project->ID = 1;
 -	$project->Name = "Project 1";
 -	$project->CreatorUserName = "Customer A";
 -	$project->ManagerUserName = "Manager A";
 -
 -	$customer = new TimeTrackerUser();
 -	$customer->ID = 1;
 -	$customer->Name = "Customer A";
 -	
 -	$manager = new TimeTrackerUser();
 -	$manager->ID = 2;
 -	$manager->Name = "Manager A";
 -	
 -	if(($conn = $this->connection) instanceof MockTSqlMapper)
 -	{
 -		//return the customer and manager
 -		$conn->setReturnValue('queryForObject', 
 -				$customer, array('GetUserByName', 'Customer A'));
 -		$conn->setReturnValue('queryForObject', 
 -				$manager, array('GetUserByName', 'Manager A'));
 -		
 -		//project does not exist
 -		$conn->setReturnValue('queryForObject', 
 -				null, array('GetProjectByName', 'Project 1'));
 -		
 -		$param['project'] = $project;
 -		$param['creator'] = $customer->ID;
 -		$param['manager'] = $manager->ID; 
 -		
 -		$conn->setReturnValue('insert', true, 
 -				array('CreateNewProject', $param));
 -		$conn->setReturnReference('queryForObject', 
 -				$project, array('GetProjectByID', 1));
 -				
 -		//we expect queryForObject to be called 3 times
 -		$conn->expectMinimumCallCount('queryForObject', 3);
 -		$conn->expectAtLeastOnce('insert');
 -	}
 -
 -	$this->assertTrue($this->dao->createNewProject($project));		
 -	$this->assertEqual($this->dao->getProjectByID(1), $project);
 -}
 -</com:TTextHighlighter>
 -</p>
 -<p>It may seem very weird that there is so much code in the tests
 -and why we even bother to write all these test codes. Well, using the
 -above test code we have the following advantages.</p>
 -<div class="info"><b class="tip">Advantages of Mock</b>
 -<ol>
 -	<li>we don't need a real database base connection to test the code, 
 -	this means we can start relying on tested code ealier</li>
 -	<li>when a test fails we know that problem is not part of the database</li> 
 -	<li>when a test fail, we can quickly pin point the problem</li>
 -	<li>the test suite gives us the confidence to refactor our code</li>
 -</ol>
 -</div>
 -
 -<p>Of couse, the test will not be able to cover the higher interactions, such as
 -the user interface, so intergration or functional web test will be used later on.
 -</p>
 -
 -<p>So how did we come up with the above tests? We started simple, then we
 -ask what sort of things it should handle. We assume that the connection object
 -work as expect or known to be unexpected and see how the method we want to test handle
 -these situations.</p>
 -
 -<p>If we run the above test, we will be faced with numerous errors. First will be
 -that the <tt>TimeTrackerUser</tt> can not be found.</p>
 -
 -<h1>Creating a new User Class</h1>
 -<p>Notice that the <tt>Project</tt> class contains <tt>CreatorUserName</tt> 
 -and <tt>ManagerUserName</tt> properties. So at some point we
 -are going to need at least one <tt>User</tt> class. We shall name the class as
 -<tt>TimeTrackerUser</tt> and save it as <tt>APP_CODE/TimeTrackerUser.php</tt>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -<?php
 -Prado::using('System.Security.TUser');
 -Prado::using('System.Security.TUserManager');
 -class TimeTrackerUser extends TUser
 -{
 -	private $_ID;
 -	
 -	public function __construct()
 -	{
 -		parent::__construct(new TUserManager());
 -	}
 -		
 -	public function getID(){ return $this->_ID; }
 -	
 -	public function setID($value)
 -	{ 
 -		if(is_null($this->_ID))
 -			$this->_ID = $value;
 -		else
 -			throw new TimeTrackerUserException(
 -				'timetracker_user_readonly_id');
 -	}
 -}
 -?>
 -</com:TTextHighlighter>
 -
 -<h1>Custom Exceptions</h1>
 -<p>We enforce that the ID of the user to be read-only once it has been
 -set by throwing a custom exception. Prado's exception classes
 -uses a string key to find a localized exception string containing more
 -detailed description of the exception. The default exception messages
 -are stored in the <tt>framework/Exceptions/messages.txt</tt>. This
 -file location can be changed by overriding the <tt>getErrorMessageFile()</tt>
 -method of <tt>TException</tt> class. We define a custom exception class
 -for all Time Tracker application exceptions as <tt>TimeTrackerException</tt>
 -and save the class as <tt>APP_CODE/TimeTrackerException.php</tt>.</p>
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -<?php
 -class TimeTrackerException extends TException
 -{
 -	/**
 -	 * @return string path to the error message file
 -	 */
 -	protected function getErrorMessageFile()
 -	{
 -        return dirname(__FILE__).'/exceptions.txt';
 -	}	
 -}
 -?>
 -</com:TTextHighlighter>
 -
 -<p>We then create a <tt>exceptions.txt</tt> file in the <tt>APP_CODE</tt>
 -directory with the following content.</p>
 -
 -<com:TTextHighlighter Language="text" CssClass="source">
 -timetracker_user_readonly_id 	= Time tracker user ID is read-only.
 -</com:TTextHighlighter>
 -
 -<p>Additional parameters passed in the exception constructor can be
 -added the message string using <tt>{0}</tt> as the first additional parameter,
 -and <tt>{1}</tt> as the second additional parameter, and so on.
 -For example, suppose we want to raise the follow exception.
 -</p> 
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -throw new TimeTrackerException('project_exists', $projectName);
 -</com:TTextHighlighter>
 -
 -<p>The exception error message in <tt>exceptions.txt</tt> may contain something like:</p>
 -<com:TTextHighlighter Language="text" CssClass="source">
 -project_exists 	= Time tracker project '{0}' already exists.
 -</com:TTextHighlighter>
 -
 -<h1>Completing the test case</h1>
 -<p>From the unit test code, we can pretty much see what the implementation
 -for <tt>createNewProject()</tt> will look like.</p>
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -public function createNewProject($project)
 -{
 -	$sqlmap = $this->getConnection();
 -	$creator = $sqlmap->queryForObject('GetUserByName', $project->CreatorUserName);
 -	$manager = $sqlmap->queryForObject('GetUserByName', $project->ManagerUserName);
 -	$exists = $sqlmap->queryForObject('GetProjectByName', $project->Name);
 -	if($exists)
 -	{
 -		throw new TimeTrackerException(
 -				'project_exists', $project->Name);
 -	}
 -	else if(!$creator || !$manager)
 -	{
 -		throw new TimeTrackerException(
 -				'invalid_creator_and_manager',
 -				$project->Name, $project->CreatorUserName, 
 -				$project->ManagerUserName); 
 -	}
 -	else
 -	{
 -		$param['project'] = $project;
 -		$param['creator'] = $creator->ID;
 -		$param['manager'] = $manager->ID; 
 -		return $sqlmap->insert('CreateNewProject', $param);         
 -	}
 -}
 -</com:TTextHighlighter>
 -
 -<div class="tip"><b class="tip">Tip:</b>
 -A hierachy of exception class can be used to have fine exception handling.
 -Since this is a small project and for simplicity, we shall use the application level
 -<tt>TimeTrackerException</tt> exception class for most exception cases. 
 -</div>
 -
 -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/UsingSQLMap.page b/demos/time-tracker/protected/pages/Docs/UsingSQLMap.page deleted file mode 100644 index cc2abf4f..00000000 --- a/demos/time-tracker/protected/pages/Docs/UsingSQLMap.page +++ /dev/null @@ -1,210 +0,0 @@ -<com:TContent ID="body">
 -<h1>Using SQLMap Data Mapper</h1>
 -<p>Before proceeding with write the code to pass the test in the previous section, we shall
 -make a design decision. We shall use SQLMap as our data access layer. Note
 -that <b>SQLMap is only available</b> offically in <b>Prado 3.1</b> or later.</p>
 -
 -<p>SQLMap is an PHP implemenation of an Object/Relational 
 -data mapper. SQLMap has the following basic features:
 -<ol>
 -	<li>collects all the Structured Query Language
 -(SQL) statements in an external XML file</li>
 -	<li>Maps data return from database queries into PHP objects</li>
 -	<li>Takes PHP objects as parameters in SQL queries</li>
 -</ol>
 -<p>SQLMap can be seen as a generic data mapper, rather than an
 -Object Relational Mapping (ORM) solution.</p>
 -
 -<p>The SQLMap API consists of the following methods. See the <a href="sqlmap">SQLMap manual</a> 
 -for further details.</p>
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -/* Query API */
 -public function queryForObject($statementName, $parameter=null, $result=null);
 -public function queryForList($statementName, $parameter=null, $result=null,
 -                                $skip=-1, $max=-1);
 -public function queryForPagedList($statementName, $parameter=null, $pageSize=10);
 -public function queryForMap($statementName, $parameter=null,
 -                                $keyProperty=null, $valueProperty=null);
 -public function insert($statementName, $parameter=null)
 -public function update($statementName, $parameter=null)
 -public function delete($statementName, $parameter=null)
 -
 -/* Connection API */
 -public function openConnection()
 -public function closeConnection()
 -
 -/* Transaction API */
 -public function beginTransaction()
 -public function commitTransaction()
 -public function rollBackTransaction()
 -</com:TTextHighlighter>
 -
 -<h2>Fetch and Inserting Data Using SQLMap</h2>
 -<p>Back to our <tt>ProjectDao</tt> class, for testing we shall write the code
 -assuming we have an SQLMap client instance. The SQLMap client or connection
 -will be mocked or faked using a proxy. Later on, we shall extend our tests,
 -to become an intergration test, to include
 -a test database connection.</p>
 -
 -<h2>Creating a SQLMap connection</h2>
 -<p>We can test the <tt>ProjectDao</tt> using mock objects (see SimpleTest documentation
 -regarding mock objects) or using a real database connection. In PHP version
 -5.0.x, the sqlite database client is bundled by default. For version 5.1 or later
 -the sqlite database client is available as an extension. We shall use a sqlite
 -database to conduct our unit tests because the database can be restored to
 -the orginal state by just reloading the orginal database file.</p>
 -
 -<div class="info"><b class="tip">Comment:</b>
 -Unit tests using mocked objects may be too ridget as we need to mock
 -the connection object and thus the test is of the grey-box/white-box variaity.
 -That is, you are actually testing the implementation of the object under test
 -consideration. Thus, any changes to the implementation of the objects
 -under tests may actually cause the tests to fail. Black box tests may
 -be more preferable, as it should only test the class interface (the method or 
 -function details such as parameters and may be return values). A further 
 -disadvantage when using mocks for complex database connection is the complexity
 -required in setting the mocks for testing.
 -</div>
 -
 -<p>First, let us define the database table for projects.</p>
 -<com:TTextHighlighter Language="sql" CssClass="source">
 -Field               Type            Null
 -----------------------------------------
 -ProjectID           INTEGER         Yes
 -Name                VARCHAR(255)    No
 -Description         VARCHAR(255)    No
 -CreationDate        INT             No
 -Disabled            INT(1)          No
 -EstimateDuration    INT             No
 -CompletionDate      INT             No
 -CreatorID           INTEGER         No
 -ManagerID           INTEGER         Yes 
 -</com:TTextHighlighter>	
 -
 -<p>The corresponding SQLite query to create the table is given below.</p>
 -
 -<com:TTextHighlighter Language="sql" CssClass="source">
 -CREATE TABLE projects ( 
 -	ProjectID INTEGER PRIMARY KEY, 
 -	Name VARCHAR(255) NOT NULL, 
 -	Description VARCHAR(255) NOT NULL, 
 -	CreationDate INT NOT NULL, 
 -	Disabled INT(1) NOT NULL, 
 -	EstimateDuration INT NOT NULL, 
 -	CompletionDate INT NOT NULL, 
 -	CreatorID INTEGER NOT NULL, 
 -	ManagerID INTEGER 
 -);
 -CREATE UNIQUE INDEX projects_Name ON projects(Name);
 -CREATE INDEX project_name_index ON projects(Name);
 -</com:TTextHighlighter>
 -
 -<h2>Testing with Mocked Database Connection</h2>
 -<p>At this point, we have said nothing about databases. To create some unit tests
 -for the <tt>ProjectDao</tt> class, we are not going to use real database connections
 -but using a Mocked <tt>TSqlMapper</tt>. We modifiy the test as follows.
 -</p>
 -<com:TTextHighlighter Language="php" CssClass="source">
 -Prado::using('Application.APP_CODE.*');
 -Prado::using('System.DataAccess.SQLMap.TSqlMapper');
 -
 -Mock::generate('TSqlMapper');
 -
 -class ProjectDaoTestCase extends UnitTestCase
 -{
 -	protected $dao;
 -	protected $connection;
 -	
 -	function setup()
 -	{
 -		$this->dao= new ProjectDao();
 -		$this->connection = new MockTSqlMapper($this);
 -		$this->dao->setConnection($this->connection);
 -	}
 -
 -	function testProjectDaoCanCreateNewProject()
 -	{
 -		$project = new Project();
 -		$project->Name = "Project 1";
 -
 -		if(($conn = $this->connection) instanceof MockTSqlMapper)
 -		{
 -			$conn->expectOnce('insert', array('CreateNewProject', $project));
 -			$conn->setReturnValue('insert', true);
 -			
 -			$conn->expectOnce('queryForObject', array('GetProjectByID', 1));
 -			$conn->setReturnReference('queryForObject', $project);
 -		}
 -
 -		$this->assertTrue($this->dao->createNewProject($project));		
 -		$this->assertEqual($this->dao->getProjectByID(1), $project);
 -	}
 -}
 -</com:TTextHighlighter>
 -<p>The test code looks slight more complicated because later on we want to
 -test the same assertions against some real data.</p>
 -<p>
 -In the first two lines above, we simply import the business code and the <tt>TSqlMapper</tt> class.
 -We generate a <tt>MockTSqlMapper</tt>, a mock class or <tt>TSqlMapper</tt> using 
 -<tt>Mock::generate('TSqlMapper')</tt>. The method <tt>Mock::generate()</tt> is available from
 -the SimpleTest unit testing framework. An instance of <tt>MockTSqlMapper</tt>
 -will be used as our test connection for the DAO objects. This allows us to interogate the
 -internal workings of our <tt>ProjectDao</tt> class. 
 -</p>
 -
 -<p>In the <tt>setup()</tt> (this method is called before every test method), we create an instance of 
 -<tt>ProjectDao</tt> and set the connection to an instance of <tt>MockTSqlMapper</tt>.
 -</p>
 -
 -<h2>Testing internal workings of ProjectDao</h2>
 -
 -<p>So how do we test the internal workings of the ProjectDao <tt>createNewProject</tt> method?
 -First, we assume that the connection object will perform the correct database insertion and queries.
 -Then, we set the return value of the MockTSqlMapper instance to return what we have assumed. 
 -In addition, we expect that the TSqlMapper method <tt>queryForObject</tt> is called only once with 
 -the parameters we have assumed (e.g. <tt>$project</tt>). See the SimpleTest tutorial for further details regarding
 -unit testing with Mocks.
 -</p>
 -
 -<p>In our assertions and expectations, we have
 -<com:TTextHighlighter Language="php" CssClass="source">
 -$conn->expectOnce('insert', array('CreateNewProject', $project));
 -$conn->setReturnValue('insert', true);
 -
 -$this->assertTrue($this->dao->createNewProject($project));		
 -</com:TTextHighlighter>
 -This means that, we expect the <tt>createNewProject</tt> method in <tt>ProjectDao</tt>
 -to call the TSqlMapper method <tt>insert</tt> with parameter <tt>$project</tt> only once.
 -In addition, we <b>assume</b> that the returned value from the <tt>insert</tt> method of TSqlMapper
 -returns <tt>true</tt>. Finally, we test the <tt>createNewProject</tt> method with an assertion.
 -</p>
 -
 -<p>We now run the unit tests, we see that there are some failures or errors. Since we 
 -have not created any code in <tt>ProjectDao</tt> that performs what we want, the tests will fail. 
 -So lets make these test pass, we add some code to <tt>ProjectDao</tt> class. 
 -
 -<com:TTextHighlighter Language="php" CssClass="source">
 -class ProjectDao extends BaseDao
 -{
 -	public function createNewProject($project)
 -	{
 -		$sqlmap = $this->getConnection();
 -		return $sqlmap->insert('CreateNewProject', $project);	
 -	} 
 -	
 -	public function getProjectByID($projectID)
 -	{
 -		$sqlmap = $this->getConnection();
 -		return $sqlmap->queryForObject('GetProjectByID', $projectID);
 -	}
 -}
 -</com:TTextHighlighter>
 -</p>
 -
 -<p>If we run the unit tests again, we should see a green bar indicating that the tests have passed.
 -We can now proceed further and add more tests. Of course, the above test does not cover many
 -conditions, such as, <i>what happens if the project already exists?</i>, the details of these
 -tests is the subject of the next section. The full test suite can be found in the source.
 -</p>
 -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/WritingFunctionalTest.page b/demos/time-tracker/protected/pages/Docs/WritingFunctionalTest.page deleted file mode 100644 index b4da0952..00000000 --- a/demos/time-tracker/protected/pages/Docs/WritingFunctionalTest.page +++ /dev/null @@ -1,39 +0,0 @@ -<com:TContent ID="body"> -<h1>Writing a Functional Web Test</h1> -<p>In addition to unit testing, we shall also do some functional -testing or web testing. Functional tests are, in this case, basically automated tests that will  -interact with the overall web application, as if it was the user, while checking the output for correctness. -The functional test tool we shall use here is based on <a href="http://selenium.openqa.org/">Selenium</a> where the test cases can be written and run using PHP and SimpleTest. -</p> -<com:TTextHighlighter> -<?php -class HelloPradoTestCase extends SeleniumTestCase -{ -	function test() -	{ -		$this->open('../index.php'); -		$this->assertTextPresent('Welcome to Prado!'); -	} -} -?> -</com:TTextHighlighter> -<p>Save the code as <tt>HelloPradoTestCase.php</tt> in the <tt>document_root/time-tracker/tests/functional/</tt> -directory.</p> - -<p> -Functional test cases are written very similar to unit test cases. The method such as  -<tt>open($url)</tt> are those found in Selenium. All the methods available in Selenium are available. -</p> - -<h2>Run your first unit test case from your browser</h2> -<p>Point your browser to your development server's unit test case runner, e.g. -	<tt>http://web-server-address/time-tracker/tests/functional.php</tt>. You should see the following	 -	<img src="<%~ functional_test1.png %>" class="figure"/> -	<div class="caption"><b>Figure 4:</b> Functional test runner</div> -</p> -<p>Clicking on the <b>All</b> button, you should see -	<img src="<%~ functional_test2.png %>" class="figure"/> -	<div class="caption"><b>Figure 5:</b> Functional test success</div> -</p>	  - -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page b/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page deleted file mode 100644 index 77bdcbe6..00000000 --- a/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page +++ /dev/null @@ -1,86 +0,0 @@ -<com:TContent ID="body"> -<h1>Writing a Unit Test</h1> -<p>Before we begin to write our business logic and code, we shall  -proceed with the path of <a href="http://tdd.com">test driven development</a> (TDD), or at least take -some part of that process.</p> - -<p>Unit testing is a useful tool when we want to start to test -	our individual business logic classes.   -	The <tt>tests/unit</tt> directory will be used to hold the unit test  -	cases and <tt>tests/functional</tt> directory -	to hold the function test cases. -</p> - -<h2>Write a unit test case</h2> -<p>We will start be writing a very simple unit test case. Notice -that we are writing the test case <b>first</b>.</p> -<com:TTextHighlighter Language="php" CssClass="source"> -<?php -class ProjectTestCase extends UnitTestCase -{ -	function testProjectClassExists() -	{ -		$project = new Project(); -		$this->pass(); -	} -} -?> -</com:TTextHighlighter> -<p>Save the code as <tt>ProjectTestCase.php</tt> in the <tt>document_root/time-tracker/tests/unit/</tt> -directory.</p> - -<h2>Run your first unit test case from your browser</h2> -<p>Point your browser to your development server's unit test case runner, e.g. -	<tt>http://web-server-address/time-tracker/tests/unit.php</tt>. You should see the following	 -<img src="<%~ unit_test1.png %>" class="figure"/> -<div class="caption"><b>Figure 1:</b> Unit test runner</div> -</p> -<p>Clicking on the <tt>ProjectTestCase.php</tt> link, you should see  -<img src="<%~ unit_test2.png %>" class="figure"/> -<div class="caption"><b>Figure 2:</b> Unit test failure</div> -</p> - -<h2>Smallest step to make the test pass.</h2> - -<p>Since we only wrote the test case and nothing else we expected -that the test case will fail at some point. Obviously, we need create  -a class <tt>Project</tt>, so lets define the <tt>Project</tt> class.</p> -<com:TTextHighlighter Language="php" CssClass="source"> -<?php -class Project -{ -} -?> -</com:TTextHighlighter> -<p>We save the above code as <tt>time-tracker/protected/pages/APP_CODE/Project.php</tt>. -	Where the <tt>APP_CODE</tt> directory will contain most of the business logic code  -	for the Time Tracker application.</p> -<p>Now, we also need to add the following line in our test case so as to  -include the <tt>Project</tt> class file when running the tests.</p> - -<com:TTextHighlighter Language="php" CssClass="source"> -<?php -Prado::using('Application.APP_CODE.Project'); -class ProjectTestCase extends UnitTestCase -{ -	... -} -?> -</com:TTextHighlighter> - -<div class="info"><b>Info:</b> -The statement <tt>Prado::using('Application.APP_CODE.Project')</tt> basically  -loads the <tt>Project.php</tt> class file. It assumes that a class name <tt>Project</tt> has filename <tt>Project.php</tt>. -For futher details regarding <tt>Prado::using</tt> can be found in <a href="http://www.pradosoft.com/demos/quickstart/index.php?page=Fundamentals.Components#704">Prado Namespaces</a> documentation. -</div> - -<p>Run the unit test runner again, we see that the test has passed. -	<img src="<%~ unit_test3.png %>" class="figure"/> -	<div class="caption"><b>Figure 3:</b> Unit test success</div> -</p>	 -<p> -Later on, we shall write more test cases. See the  -<a href="http://www.lastcraft.com/simple_test.php">SimpleTest documentation</a>  -for detailed tutorial on writing test cases.</p> - -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/config.xml b/demos/time-tracker/protected/pages/Docs/config.xml deleted file mode 100644 index e8fdc3fe..00000000 --- a/demos/time-tracker/protected/pages/Docs/config.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
 -
 -<configuration>
 -
 -    <modules>
 -        <module id="theme"
 -                class="System.Web.UI.TThemeManager"
 -                BasePath="Quickstart.themes"
 -                BaseUrl="../quickstart/themes" />
 -    </modules>
 -  <pages MasterClass="Application.pages.Docs.Layout" Theme="PradoSoft"/>
 -</configuration>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/db.png b/demos/time-tracker/protected/pages/Docs/db.png Binary files differdeleted file mode 100644 index efdcc1e5..00000000 --- a/demos/time-tracker/protected/pages/Docs/db.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/Docs/functional_test1.png b/demos/time-tracker/protected/pages/Docs/functional_test1.png Binary files differdeleted file mode 100644 index 33908734..00000000 --- a/demos/time-tracker/protected/pages/Docs/functional_test1.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/Docs/functional_test2.png b/demos/time-tracker/protected/pages/Docs/functional_test2.png Binary files differdeleted file mode 100644 index fb507e72..00000000 --- a/demos/time-tracker/protected/pages/Docs/functional_test2.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/Docs/preface.page b/demos/time-tracker/protected/pages/Docs/preface.page deleted file mode 100644 index fa0ba5c3..00000000 --- a/demos/time-tracker/protected/pages/Docs/preface.page +++ /dev/null @@ -1,19 +0,0 @@ -<com:TContent ID="body">
 -<h1>Prado Time Tracker</h1>
 -<p>This documentation is complete walk-through guide detailing the
 -steps involved in implementating of the Prado Time Tracker web application.
 -</p>
 -<h2>Target Audience</h2>
 -<p>The guide is intended for readers who has some experience
 -using PHP version 5 and some basic concepts of Object-Oriented application
 -design. The guide will assume that the reader understands the primary concepts
 -of class, methods, class inheritance, and other basic features offered by PHP
 -version 5 or later.</p>
 -<h2>Questions and Comments</h2>
 -<p>Readers are encouraged to ask questions as the forum regarding any
 -particular aspect of this documentation. Comment and constructive criticisms
 -are most welcome. Questions and comments may be directed at
 -<a href="http://www.pradosoft.com/forum/">http://www.pradosoft.com/forum/</a>.
 -</p>
 -
 -</com:TContent>
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/Docs/project1.png b/demos/time-tracker/protected/pages/Docs/project1.png Binary files differdeleted file mode 100644 index a250a943..00000000 --- a/demos/time-tracker/protected/pages/Docs/project1.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/Docs/unit_test1.png b/demos/time-tracker/protected/pages/Docs/unit_test1.png Binary files differdeleted file mode 100644 index 66b62e19..00000000 --- a/demos/time-tracker/protected/pages/Docs/unit_test1.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/Docs/unit_test2.png b/demos/time-tracker/protected/pages/Docs/unit_test2.png Binary files differdeleted file mode 100644 index e33544d2..00000000 --- a/demos/time-tracker/protected/pages/Docs/unit_test2.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/Docs/unit_test3.png b/demos/time-tracker/protected/pages/Docs/unit_test3.png Binary files differdeleted file mode 100644 index bbc04551..00000000 --- a/demos/time-tracker/protected/pages/Docs/unit_test3.png +++ /dev/null diff --git a/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl index ad33217b..44aea22b 100644 --- a/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl +++ b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl @@ -24,7 +24,6 @@  		Visible=<%= !$this->User->getIsGuest() %> />
  </h2>
  <h2 class="help"><a href="?page=Welcome">Help</a></h2>
 -<h2 class="guide"><a href="?page=Docs.Home">Implementation Guide</a></h2>
  </div>
  <com:Application.pages.TimeTracker.SiteMap
 diff --git a/demos/time-tracker/protected/pages/Welcome.page b/demos/time-tracker/protected/pages/Welcome.page index 65ada02d..83567cd0 100644 --- a/demos/time-tracker/protected/pages/Welcome.page +++ b/demos/time-tracker/protected/pages/Welcome.page @@ -89,8 +89,7 @@  		Visitors can register by clicking the <strong>Create new </strong>user link on the home page.
  		New members are activated automatically, and are assigned to a role as specified in the <tt>application.xml</tt> file.
  		You can manage users (for example, assign them to a role) when login as administrator.
 -		For details, see <a href="#AppendixA">Appendix A</a>.</p>
 -		
 +	</p>		
  	<hr />
  	<h2>Projects and Time Entries</h2>
 @@ -132,37 +131,6 @@  		<li>Click <strong>Generate Report</strong>.</li>
  	</ol>
 -	<hr />
 -	<a name="AppendixA" />
 -	<h2>Appendix A - Manually Managing Members and Roles</h2>
 -	<p>
 -		Your Time Tracker Web site allows visitors to register as members.
 -		Members have specific privileges defined by a role you assign to them.
 -		A special administrative role has rights to perform all functions in the site.</p>
 -	<p>
 -		To create a user (member):</p>
 -	<ol>
 -		<li>Login as administrator, click <strong>Create New User</strong>.
 -		</li>
 -		<li>...</li>
 -	</ol>
 -	<p>
 -		To modify an existing member's role:</p>
 -	<ol>
 -		<li>Login as administrator, click <strong>List Users</strong>.
 -		</li>
 -		<li>...</li>
 -	</ol>
 -
 -	<hr />
 -	
 -	<h2>Appendix B - Publishing Your Site</h2>
 -	<p>
 -		When you are ready to share the Web site with others, you can copy it to your Web server.
 -		You need to know the File Transfer Protocol (FTP) address of your server, and if required, the user name and password assigned to you.</p>
 -	<ol>
 -		<li>...</li>
 -	</ol>
  </body>
  </html>
  | 
