Reorganize system folder
This commit is contained in:
parent
2c20d3b83e
commit
327ba4bf6f
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/sys/db/.travis.yml
|
||||||
|
/sys/db/docs/*
|
||||||
|
/sys/db/phpdoc.dist.xml
|
||||||
|
/sys/db/README.md
|
||||||
|
/sys/db/tests/*
|
@ -8,9 +8,9 @@
|
|||||||
<p>Backtrace: </p>
|
<p>Backtrace: </p>
|
||||||
<?php foreach($exception->getTrace() as $error): ?>
|
<?php foreach($exception->getTrace() as $error): ?>
|
||||||
|
|
||||||
<?php if(isset($error['file']) && ! stristr($error['file'], SYS_PATH)): ?>
|
<?php if (isset($error['file']) && ! stristr($error['file'], MM_SYS_PATH)): ?>
|
||||||
<p style="margin-left:10px">
|
<p style="margin-left:10px">
|
||||||
File: <?= str_replace(BASE_PATH, "", $error['file']) ?><br />
|
File: <?= str_replace(MM_BASE_PATH, "", $error['file']) ?><br />
|
||||||
Line: <?= $error['line'] ?><br />
|
Line: <?= $error['line'] ?><br />
|
||||||
Function: <?= $error['function'] ?>
|
Function: <?= $error['function'] ?>
|
||||||
</p>
|
</p>
|
||||||
|
235
docs/classes.svg
235
docs/classes.svg
@ -4,74 +4,74 @@
|
|||||||
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
|
||||||
-->
|
-->
|
||||||
<!-- Title: G Pages: 1 -->
|
<!-- Title: G Pages: 1 -->
|
||||||
<svg width="874pt" height="1192pt"
|
<svg width="874pt" height="1246pt"
|
||||||
viewBox="0.00 0.00 874.00 1192.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 874.00 1246.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 1188)">
|
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 1242)">
|
||||||
<title>G</title>
|
<title>G</title>
|
||||||
<polygon fill="white" stroke="white" points="-4,5 -4,-1188 871,-1188 871,5 -4,5"/>
|
<polygon fill="white" stroke="white" points="-4,5 -4,-1242 871,-1242 871,5 -4,5"/>
|
||||||
<g id="graph2" class="cluster"><title>cluster_default</title>
|
<g id="graph2" class="cluster"><title>cluster_default</title>
|
||||||
<polyline fill="none" stroke="none" points="218,-44 846,-44 "/>
|
<polyline fill="none" stroke="none" points="218,-44 846,-44 "/>
|
||||||
<path fill="none" stroke="none" d="M846,-44C852,-44 858,-50 858,-56"/>
|
<path fill="none" stroke="none" d="M846,-44C852,-44 858,-50 858,-56"/>
|
||||||
<polyline fill="none" stroke="none" points="858,-56 858,-1164 "/>
|
<polyline fill="none" stroke="none" points="858,-56 858,-1218 "/>
|
||||||
<path fill="none" stroke="none" d="M858,-1164C858,-1170 852,-1176 846,-1176"/>
|
<path fill="none" stroke="none" d="M858,-1218C858,-1224 852,-1230 846,-1230"/>
|
||||||
<polyline fill="none" stroke="none" points="846,-1176 218,-1176 "/>
|
<polyline fill="none" stroke="none" points="846,-1230 218,-1230 "/>
|
||||||
<path fill="none" stroke="none" d="M218,-1176C212,-1176 206,-1170 206,-1164"/>
|
<path fill="none" stroke="none" d="M218,-1230C212,-1230 206,-1224 206,-1218"/>
|
||||||
<polyline fill="none" stroke="none" points="206,-1164 206,-56 "/>
|
<polyline fill="none" stroke="none" points="206,-1218 206,-56 "/>
|
||||||
<path fill="none" stroke="none" d="M206,-56C206,-50 212,-44 218,-44"/>
|
<path fill="none" stroke="none" d="M206,-56C206,-50 212,-44 218,-44"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB_Reg -->
|
<!-- \\DB_Reg -->
|
||||||
<g id="node2" class="node"><title>\\DB_Reg</title>
|
<g id="node2" class="node"><title>\\DB_Reg</title>
|
||||||
<a xlink:href="sys.db.classes.db_reg.html" xlink:title="DB_Reg" target="_parent">
|
<a xlink:href="sys.db.classes.db_reg.html" xlink:title="DB_Reg" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="819,-1168 763,-1168 763,-1132 819,-1132 819,-1168"/>
|
<polygon fill="none" stroke="black" points="819,-1222 763,-1222 763,-1186 819,-1186 819,-1222"/>
|
||||||
<text text-anchor="middle" x="791" y="-1146.6" font-family="Courier,monospace" font-size="11.00">DB_Reg</text>
|
<text text-anchor="middle" x="791" y="-1200.6" font-family="Courier,monospace" font-size="11.00">DB_Reg</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Settings -->
|
<!-- \\Settings -->
|
||||||
<g id="node3" class="node"><title>\\Settings</title>
|
<g id="node3" class="node"><title>\\Settings</title>
|
||||||
<a xlink:href="sys.db.classes.settings.html" xlink:title="Settings" target="_parent">
|
<a xlink:href="sys.db.classes.settings.html" xlink:title="Settings" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="826,-1114 756,-1114 756,-1078 826,-1078 826,-1114"/>
|
<polygon fill="none" stroke="black" points="826,-1168 756,-1168 756,-1132 826,-1132 826,-1168"/>
|
||||||
<text text-anchor="middle" x="791" y="-1092.6" font-family="Courier,monospace" font-size="11.00">Settings</text>
|
<text text-anchor="middle" x="791" y="-1146.6" font-family="Courier,monospace" font-size="11.00">Settings</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB_SQL -->
|
<!-- \\DB_SQL -->
|
||||||
<g id="node4" class="node"><title>\\DB_SQL</title>
|
<g id="node4" class="node"><title>\\DB_SQL</title>
|
||||||
<a xlink:href="sys.db.classes.db_sql.html" xlink:title="«abstract»<br/>DB_SQL" target="_parent">
|
<a xlink:href="sys.db.classes.db_sql.html" xlink:title="«abstract»<br/>DB_SQL" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="617,-682 533,-682 533,-646 617,-646 617,-682"/>
|
<polygon fill="none" stroke="black" points="617,-736 533,-736 533,-700 617,-700 617,-736"/>
|
||||||
<text text-anchor="start" x="541" y="-669.433" font-family="Courier,monospace" font-size="11.00">«abstract»</text>
|
<text text-anchor="start" x="541" y="-723.433" font-family="Courier,monospace" font-size="11.00">«abstract»</text>
|
||||||
<text text-anchor="start" x="554.5" y="-656.233" font-family="Courier,monospace" font-size="11.00">DB_SQL</text>
|
<text text-anchor="start" x="554.5" y="-710.233" font-family="Courier,monospace" font-size="11.00">DB_SQL</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB_PDO -->
|
<!-- \\DB_PDO -->
|
||||||
<g id="node5" class="node"><title>\\DB_PDO</title>
|
<g id="node5" class="node"><title>\\DB_PDO</title>
|
||||||
<a xlink:href="sys.db.classes.db_pdo.html" xlink:title="«abstract»<br/>DB_PDO" target="_parent">
|
<a xlink:href="sys.db.classes.db_pdo.html" xlink:title="«abstract»<br/>DB_PDO" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="617,-223 533,-223 533,-187 617,-187 617,-223"/>
|
<polygon fill="none" stroke="black" points="617,-277 533,-277 533,-241 617,-241 617,-277"/>
|
||||||
<text text-anchor="start" x="541" y="-210.433" font-family="Courier,monospace" font-size="11.00">«abstract»</text>
|
<text text-anchor="start" x="541" y="-264.433" font-family="Courier,monospace" font-size="11.00">«abstract»</text>
|
||||||
<text text-anchor="start" x="554.5" y="-197.233" font-family="Courier,monospace" font-size="11.00">DB_PDO</text>
|
<text text-anchor="start" x="554.5" y="-251.233" font-family="Courier,monospace" font-size="11.00">DB_PDO</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\PDO -->
|
<!-- \\PDO -->
|
||||||
<g id="node34" class="node"><title>\\PDO</title>
|
<g id="node35" class="node"><title>\\PDO</title>
|
||||||
<ellipse fill="none" stroke="black" cx="379" cy="-18" rx="35.0527" ry="18"/>
|
<ellipse fill="none" stroke="black" cx="379" cy="-18" rx="35.0527" ry="18"/>
|
||||||
<text text-anchor="middle" x="379" y="-13.4" font-family="Times Roman,serif" font-size="14.00" fill="gray">\PDO</text>
|
<text text-anchor="middle" x="379" y="-13.4" font-family="Times Roman,serif" font-size="14.00" fill="gray">\PDO</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB_PDO->\\PDO -->
|
<!-- \\DB_PDO->\\PDO -->
|
||||||
<g id="edge3" class="edge"><title>\\DB_PDO->\\PDO</title>
|
<g id="edge3" class="edge"><title>\\DB_PDO->\\PDO</title>
|
||||||
<path fill="none" stroke="black" d="M532.431,-201.202C517.741,-198.13 501.983,-192.666 490,-183 434.617,-138.323 467.115,-91.488 418,-40 416.783,-38.7238 415.475,-37.5011 414.102,-36.3323"/>
|
<path fill="none" stroke="black" d="M532.23,-256.037C517.348,-253.062 501.515,-247.447 490,-237 420.961,-174.361 478.324,-111.07 418,-40 416.859,-38.6554 415.613,-37.3763 414.291,-36.1617"/>
|
||||||
<polygon fill="none" stroke="black" points="415.855,-33.2795 405.708,-30.2321 411.74,-38.9422 415.855,-33.2795"/>
|
<polygon fill="none" stroke="black" points="416.149,-33.1773 406.073,-29.9031 411.908,-38.7463 416.149,-33.1773"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Query_Builder -->
|
<!-- \\Query_Builder -->
|
||||||
<g id="node6" class="node"><title>\\Query_Builder</title>
|
<g id="node6" class="node"><title>\\Query_Builder</title>
|
||||||
<a xlink:href="sys.db.classes.query_builder.html" xlink:title="Query_Builder" target="_parent">
|
<a xlink:href="sys.db.classes.query_builder.html" xlink:title="Query_Builder" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="627,-466 523,-466 523,-430 627,-430 627,-466"/>
|
<polygon fill="none" stroke="black" points="627,-520 523,-520 523,-484 627,-484 627,-520"/>
|
||||||
<text text-anchor="middle" x="575" y="-444.6" font-family="Courier,monospace" font-size="11.00">Query_Builder</text>
|
<text text-anchor="middle" x="575" y="-498.6" font-family="Courier,monospace" font-size="11.00">Query_Builder</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB_Util -->
|
<!-- \\DB_Util -->
|
||||||
<g id="node7" class="node"><title>\\DB_Util</title>
|
<g id="node7" class="node"><title>\\DB_Util</title>
|
||||||
<a xlink:href="sys.db.classes.db_util.html" xlink:title="«abstract»<br/>DB_Util" target="_parent">
|
<a xlink:href="sys.db.classes.db_util.html" xlink:title="«abstract»<br/>DB_Util" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="617,-952 533,-952 533,-916 617,-916 617,-952"/>
|
<polygon fill="none" stroke="black" points="617,-1006 533,-1006 533,-970 617,-970 617,-1006"/>
|
||||||
<text text-anchor="start" x="541" y="-939.433" font-family="Courier,monospace" font-size="11.00">«abstract»</text>
|
<text text-anchor="start" x="541" y="-993.433" font-family="Courier,monospace" font-size="11.00">«abstract»</text>
|
||||||
<text text-anchor="start" x="551" y="-926.233" font-family="Courier,monospace" font-size="11.00">DB_Util</text>
|
<text text-anchor="start" x="551" y="-980.233" font-family="Courier,monospace" font-size="11.00">DB_Util</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\PgSQL_SQL -->
|
<!-- \\PgSQL_SQL -->
|
||||||
@ -83,8 +83,8 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\PgSQL_SQL->\\DB_SQL -->
|
<!-- \\PgSQL_SQL->\\DB_SQL -->
|
||||||
<g id="edge5" class="edge"><title>\\PgSQL_SQL->\\DB_SQL</title>
|
<g id="edge5" class="edge"><title>\\PgSQL_SQL->\\DB_SQL</title>
|
||||||
<path fill="none" stroke="black" d="M752.384,-708.346C717.629,-699.657 666.251,-686.813 627.723,-677.181"/>
|
<path fill="none" stroke="black" d="M752.384,-718C717.629,-718 666.251,-718 627.723,-718"/>
|
||||||
<polygon fill="none" stroke="black" points="628.273,-673.711 617.723,-674.681 626.576,-680.502 628.273,-673.711"/>
|
<polygon fill="none" stroke="black" points="627.723,-714.5 617.723,-718 627.723,-721.5 627.723,-714.5"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\PgSQL_Util -->
|
<!-- \\PgSQL_Util -->
|
||||||
<g id="node9" class="node"><title>\\PgSQL_Util</title>
|
<g id="node9" class="node"><title>\\PgSQL_Util</title>
|
||||||
@ -95,20 +95,20 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\PgSQL_Util->\\DB_Util -->
|
<!-- \\PgSQL_Util->\\DB_Util -->
|
||||||
<g id="edge7" class="edge"><title>\\PgSQL_Util->\\DB_Util</title>
|
<g id="edge7" class="edge"><title>\\PgSQL_Util->\\DB_Util</title>
|
||||||
<path fill="none" stroke="black" d="M748.84,-977.46C714.276,-968.819 665.162,-956.54 627.95,-947.237"/>
|
<path fill="none" stroke="black" d="M748.84,-988C714.276,-988 665.162,-988 627.95,-988"/>
|
||||||
<polygon fill="none" stroke="black" points="628.342,-943.728 617.792,-944.698 626.644,-950.519 628.342,-943.728"/>
|
<polygon fill="none" stroke="black" points="627.792,-984.5 617.792,-988 627.792,-991.5 627.792,-984.5"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\PgSQL -->
|
<!-- \\PgSQL -->
|
||||||
<g id="node10" class="node"><title>\\PgSQL</title>
|
<g id="node10" class="node"><title>\\PgSQL</title>
|
||||||
<a xlink:href="sys.db.drivers.pgsql.pgsql_driver.html" xlink:title="PgSQL" target="_parent">
|
<a xlink:href="sys.db.drivers.pgsql.pgsql_driver.html" xlink:title="PgSQL" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="818,-196 764,-196 764,-160 818,-160 818,-196"/>
|
<polygon fill="none" stroke="black" points="818,-142 764,-142 764,-106 818,-106 818,-142"/>
|
||||||
<text text-anchor="middle" x="791" y="-174.6" font-family="Courier,monospace" font-size="11.00">PgSQL</text>
|
<text text-anchor="middle" x="791" y="-120.6" font-family="Courier,monospace" font-size="11.00">PgSQL</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\PgSQL->\\DB_PDO -->
|
<!-- \\PgSQL->\\DB_PDO -->
|
||||||
<g id="edge9" class="edge"><title>\\PgSQL->\\DB_PDO</title>
|
<g id="edge9" class="edge"><title>\\PgSQL->\\DB_PDO</title>
|
||||||
<path fill="none" stroke="black" d="M763.643,-181.42C729.593,-185.676 670.693,-193.038 627.747,-198.407"/>
|
<path fill="none" stroke="black" d="M763.749,-133.489C753.242,-137.886 741.495,-143.76 732,-151 692.36,-181.227 702.141,-210.372 660,-237 650.233,-243.172 638.798,-247.617 627.539,-250.818"/>
|
||||||
<polygon fill="none" stroke="black" points="627.236,-194.943 617.747,-199.657 628.104,-201.889 627.236,-194.943"/>
|
<polygon fill="none" stroke="black" points="626.559,-247.456 617.736,-253.322 628.292,-254.238 626.559,-247.456"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\ODBC_Util -->
|
<!-- \\ODBC_Util -->
|
||||||
<g id="node11" class="node"><title>\\ODBC_Util</title>
|
<g id="node11" class="node"><title>\\ODBC_Util</title>
|
||||||
@ -119,8 +119,8 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\ODBC_Util->\\DB_Util -->
|
<!-- \\ODBC_Util->\\DB_Util -->
|
||||||
<g id="edge11" class="edge"><title>\\ODBC_Util->\\DB_Util</title>
|
<g id="edge11" class="edge"><title>\\ODBC_Util->\\DB_Util</title>
|
||||||
<path fill="none" stroke="black" d="M752.384,-934C717.629,-934 666.251,-934 627.723,-934"/>
|
<path fill="none" stroke="black" d="M752.384,-943.654C717.629,-952.343 666.251,-965.187 627.723,-974.819"/>
|
||||||
<polygon fill="none" stroke="black" points="627.723,-930.5 617.723,-934 627.723,-937.5 627.723,-930.5"/>
|
<polygon fill="none" stroke="black" points="626.576,-971.498 617.723,-977.319 628.273,-978.289 626.576,-971.498"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\ODBC_SQL -->
|
<!-- \\ODBC_SQL -->
|
||||||
<g id="node12" class="node"><title>\\ODBC_SQL</title>
|
<g id="node12" class="node"><title>\\ODBC_SQL</title>
|
||||||
@ -131,20 +131,20 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\ODBC_SQL->\\DB_SQL -->
|
<!-- \\ODBC_SQL->\\DB_SQL -->
|
||||||
<g id="edge13" class="edge"><title>\\ODBC_SQL->\\DB_SQL</title>
|
<g id="edge13" class="edge"><title>\\ODBC_SQL->\\DB_SQL</title>
|
||||||
<path fill="none" stroke="black" d="M755.815,-664C721.064,-664 667.487,-664 627.664,-664"/>
|
<path fill="none" stroke="black" d="M755.815,-672.796C720.991,-681.502 667.26,-694.935 627.41,-704.897"/>
|
||||||
<polygon fill="none" stroke="black" points="627.598,-660.5 617.598,-664 627.598,-667.5 627.598,-660.5"/>
|
<polygon fill="none" stroke="black" points="626.451,-701.53 617.598,-707.35 628.148,-708.321 626.451,-701.53"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\ODBC -->
|
<!-- \\ODBC -->
|
||||||
<g id="node13" class="node"><title>\\ODBC</title>
|
<g id="node13" class="node"><title>\\ODBC</title>
|
||||||
<a xlink:href="sys.db.drivers.odbc.odbc_driver.html" xlink:title="ODBC" target="_parent">
|
<a xlink:href="sys.db.drivers.odbc.odbc_driver.html" xlink:title="ODBC" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="818,-142 764,-142 764,-106 818,-106 818,-142"/>
|
<polygon fill="none" stroke="black" points="818,-412 764,-412 764,-376 818,-376 818,-412"/>
|
||||||
<text text-anchor="middle" x="791" y="-120.6" font-family="Courier,monospace" font-size="11.00">ODBC</text>
|
<text text-anchor="middle" x="791" y="-390.6" font-family="Courier,monospace" font-size="11.00">ODBC</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\ODBC->\\DB_PDO -->
|
<!-- \\ODBC->\\DB_PDO -->
|
||||||
<g id="edge15" class="edge"><title>\\ODBC->\\DB_PDO</title>
|
<g id="edge15" class="edge"><title>\\ODBC->\\DB_PDO</title>
|
||||||
<path fill="none" stroke="black" d="M763.695,-136.44C726.868,-153.197 665.25,-181.153 660,-183 649.651,-186.64 638.403,-189.972 627.58,-192.882"/>
|
<path fill="none" stroke="black" d="M763.782,-382.728C753.615,-378.212 742.093,-372.723 732,-367 686.756,-341.342 637.869,-306.466 606.878,-283.371"/>
|
||||||
<polygon fill="none" stroke="black" points="626.591,-189.523 617.797,-195.432 628.356,-196.296 626.591,-189.523"/>
|
<polygon fill="none" stroke="black" points="608.731,-280.385 598.63,-277.186 604.531,-285.985 608.731,-280.385"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MySQL_Util -->
|
<!-- \\MySQL_Util -->
|
||||||
<g id="node14" class="node"><title>\\MySQL_Util</title>
|
<g id="node14" class="node"><title>\\MySQL_Util</title>
|
||||||
@ -155,8 +155,8 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\MySQL_Util->\\DB_Util -->
|
<!-- \\MySQL_Util->\\DB_Util -->
|
||||||
<g id="edge17" class="edge"><title>\\MySQL_Util->\\DB_Util</title>
|
<g id="edge17" class="edge"><title>\\MySQL_Util->\\DB_Util</title>
|
||||||
<path fill="none" stroke="black" d="M748.325,-890.669C713.712,-899.322 664.759,-911.56 627.701,-920.825"/>
|
<path fill="none" stroke="black" d="M750.892,-898.047C744.548,-900.99 738.078,-904.043 732,-907 692.965,-925.988 649.105,-948.738 617.686,-965.287"/>
|
||||||
<polygon fill="none" stroke="black" points="626.439,-917.533 617.586,-923.354 628.136,-924.324 626.439,-917.533"/>
|
<polygon fill="none" stroke="black" points="615.972,-962.234 608.762,-969.997 619.24,-968.425 615.972,-962.234"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MySQL -->
|
<!-- \\MySQL -->
|
||||||
<g id="node15" class="node"><title>\\MySQL</title>
|
<g id="node15" class="node"><title>\\MySQL</title>
|
||||||
@ -167,8 +167,8 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\MySQL->\\DB_PDO -->
|
<!-- \\MySQL->\\DB_PDO -->
|
||||||
<g id="edge19" class="edge"><title>\\MySQL->\\DB_PDO</title>
|
<g id="edge19" class="edge"><title>\\MySQL->\\DB_PDO</title>
|
||||||
<path fill="none" stroke="black" d="M763.782,-328.728C753.615,-324.212 742.093,-318.723 732,-313 686.756,-287.342 637.869,-252.466 606.878,-229.371"/>
|
<path fill="none" stroke="black" d="M763.643,-329.741C729.449,-316.918 670.196,-294.699 627.205,-278.577"/>
|
||||||
<polygon fill="none" stroke="black" points="608.731,-226.385 598.63,-223.186 604.531,-231.985 608.731,-226.385"/>
|
<polygon fill="none" stroke="black" points="628.339,-275.264 617.747,-275.03 625.882,-281.819 628.339,-275.264"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MySQL_SQL -->
|
<!-- \\MySQL_SQL -->
|
||||||
<g id="node16" class="node"><title>\\MySQL_SQL</title>
|
<g id="node16" class="node"><title>\\MySQL_SQL</title>
|
||||||
@ -179,20 +179,20 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\MySQL_SQL->\\DB_SQL -->
|
<!-- \\MySQL_SQL->\\DB_SQL -->
|
||||||
<g id="edge21" class="edge"><title>\\MySQL_SQL->\\DB_SQL</title>
|
<g id="edge21" class="edge"><title>\\MySQL_SQL->\\DB_SQL</title>
|
||||||
<path fill="none" stroke="black" d="M751.884,-619.779C717.065,-628.484 665.851,-641.287 627.48,-650.88"/>
|
<path fill="none" stroke="black" d="M751.843,-627.606C745.196,-630.684 738.382,-633.896 732,-637 692.965,-655.988 649.105,-678.738 617.686,-695.287"/>
|
||||||
<polygon fill="none" stroke="black" points="626.374,-647.549 617.522,-653.37 628.072,-654.34 626.374,-647.549"/>
|
<polygon fill="none" stroke="black" points="615.972,-692.234 608.762,-699.997 619.24,-698.425 615.972,-692.234"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\SQLite_Util -->
|
<!-- \\SQLite_Util -->
|
||||||
<g id="node17" class="node"><title>\\SQLite_Util</title>
|
<g id="node17" class="node"><title>\\SQLite_Util</title>
|
||||||
<a xlink:href="sys.db.drivers.sqlite.sqlite_util.html" xlink:title="SQLite_Util" target="_parent">
|
<a xlink:href="sys.db.drivers.sqlite.sqlite_util.html" xlink:title="SQLite_Util" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="836,-844 746,-844 746,-808 836,-808 836,-844"/>
|
<polygon fill="none" stroke="black" points="836,-1114 746,-1114 746,-1078 836,-1078 836,-1114"/>
|
||||||
<text text-anchor="middle" x="791" y="-822.6" font-family="Courier,monospace" font-size="11.00">SQLite_Util</text>
|
<text text-anchor="middle" x="791" y="-1092.6" font-family="Courier,monospace" font-size="11.00">SQLite_Util</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\SQLite_Util->\\DB_Util -->
|
<!-- \\SQLite_Util->\\DB_Util -->
|
||||||
<g id="edge23" class="edge"><title>\\SQLite_Util->\\DB_Util</title>
|
<g id="edge23" class="edge"><title>\\SQLite_Util->\\DB_Util</title>
|
||||||
<path fill="none" stroke="black" d="M750.892,-844.047C744.548,-846.99 738.078,-850.043 732,-853 692.965,-871.988 649.105,-894.738 617.686,-911.287"/>
|
<path fill="none" stroke="black" d="M750.892,-1077.95C744.548,-1075.01 738.078,-1071.96 732,-1069 692.965,-1050.01 649.105,-1027.26 617.686,-1010.71"/>
|
||||||
<polygon fill="none" stroke="black" points="615.972,-908.234 608.762,-915.997 619.24,-914.425 615.972,-908.234"/>
|
<polygon fill="none" stroke="black" points="619.24,-1007.58 608.762,-1006 615.972,-1013.77 619.24,-1007.58"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\SQLite -->
|
<!-- \\SQLite -->
|
||||||
<g id="node18" class="node"><title>\\SQLite</title>
|
<g id="node18" class="node"><title>\\SQLite</title>
|
||||||
@ -203,20 +203,20 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\SQLite->\\DB_PDO -->
|
<!-- \\SQLite->\\DB_PDO -->
|
||||||
<g id="edge25" class="edge"><title>\\SQLite->\\DB_PDO</title>
|
<g id="edge25" class="edge"><title>\\SQLite->\\DB_PDO</title>
|
||||||
<path fill="none" stroke="black" d="M762.317,-275.244C727.929,-262.348 669.629,-240.486 627.188,-224.57"/>
|
<path fill="none" stroke="black" d="M762.317,-282.415C728.073,-278.134 670.12,-270.89 627.724,-265.591"/>
|
||||||
<polygon fill="none" stroke="black" points="628.169,-221.2 617.577,-220.966 625.711,-227.755 628.169,-221.2"/>
|
<polygon fill="none" stroke="black" points="627.934,-262.09 617.577,-264.322 627.066,-269.036 627.934,-262.09"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\SQLite_SQL -->
|
<!-- \\SQLite_SQL -->
|
||||||
<g id="node19" class="node"><title>\\SQLite_SQL</title>
|
<g id="node19" class="node"><title>\\SQLite_SQL</title>
|
||||||
<a xlink:href="sys.db.drivers.sqlite.sqlite_sql.html" xlink:title="SQLite_SQL" target="_parent">
|
<a xlink:href="sys.db.drivers.sqlite.sqlite_sql.html" xlink:title="SQLite_SQL" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="833,-574 749,-574 749,-538 833,-538 833,-574"/>
|
<polygon fill="none" stroke="black" points="833,-844 749,-844 749,-808 833,-808 833,-844"/>
|
||||||
<text text-anchor="middle" x="791" y="-552.6" font-family="Courier,monospace" font-size="11.00">SQLite_SQL</text>
|
<text text-anchor="middle" x="791" y="-822.6" font-family="Courier,monospace" font-size="11.00">SQLite_SQL</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\SQLite_SQL->\\DB_SQL -->
|
<!-- \\SQLite_SQL->\\DB_SQL -->
|
||||||
<g id="edge27" class="edge"><title>\\SQLite_SQL->\\DB_SQL</title>
|
<g id="edge27" class="edge"><title>\\SQLite_SQL->\\DB_SQL</title>
|
||||||
<path fill="none" stroke="black" d="M750.892,-574.047C744.548,-576.99 738.078,-580.043 732,-583 692.965,-601.988 649.105,-624.738 617.686,-641.287"/>
|
<path fill="none" stroke="black" d="M750.892,-807.953C744.548,-805.01 738.078,-801.957 732,-799 692.965,-780.012 649.105,-757.262 617.686,-740.713"/>
|
||||||
<polygon fill="none" stroke="black" points="615.972,-638.234 608.762,-645.997 619.24,-644.425 615.972,-638.234"/>
|
<polygon fill="none" stroke="black" points="619.24,-737.575 608.762,-736.003 615.972,-743.766 619.24,-737.575"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Firebird_SQL -->
|
<!-- \\Firebird_SQL -->
|
||||||
<g id="node20" class="node"><title>\\Firebird_SQL</title>
|
<g id="node20" class="node"><title>\\Firebird_SQL</title>
|
||||||
@ -227,8 +227,8 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\Firebird_SQL->\\DB_SQL -->
|
<!-- \\Firebird_SQL->\\DB_SQL -->
|
||||||
<g id="edge29" class="edge"><title>\\Firebird_SQL->\\DB_SQL</title>
|
<g id="edge29" class="edge"><title>\\Firebird_SQL->\\DB_SQL</title>
|
||||||
<path fill="none" stroke="black" d="M750.892,-753.953C744.548,-751.01 738.078,-747.957 732,-745 692.965,-726.012 649.105,-703.262 617.686,-686.713"/>
|
<path fill="none" stroke="black" d="M742.256,-759.814C708.168,-751.292 662.673,-739.918 627.738,-731.185"/>
|
||||||
<polygon fill="none" stroke="black" points="619.24,-683.575 608.762,-682.003 615.972,-689.766 619.24,-683.575"/>
|
<polygon fill="none" stroke="black" points="628.273,-727.711 617.723,-728.681 626.575,-734.502 628.273,-727.711"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Firebird_Result -->
|
<!-- \\Firebird_Result -->
|
||||||
<g id="node21" class="node"><title>\\Firebird_Result</title>
|
<g id="node21" class="node"><title>\\Firebird_Result</title>
|
||||||
@ -238,7 +238,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\PDOStatement -->
|
<!-- \\PDOStatement -->
|
||||||
<g id="node49" class="node"><title>\\PDOStatement</title>
|
<g id="node50" class="node"><title>\\PDOStatement</title>
|
||||||
<ellipse fill="none" stroke="black" cx="575" cy="-18" rx="85.1942" ry="18"/>
|
<ellipse fill="none" stroke="black" cx="575" cy="-18" rx="85.1942" ry="18"/>
|
||||||
<text text-anchor="middle" x="575" y="-13.4" font-family="Times Roman,serif" font-size="14.00" fill="gray">\PDOStatement</text>
|
<text text-anchor="middle" x="575" y="-13.4" font-family="Times Roman,serif" font-size="14.00" fill="gray">\PDOStatement</text>
|
||||||
</g>
|
</g>
|
||||||
@ -256,8 +256,8 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\Firebird->\\DB_PDO -->
|
<!-- \\Firebird->\\DB_PDO -->
|
||||||
<g id="edge33" class="edge"><title>\\Firebird->\\DB_PDO</title>
|
<g id="edge33" class="edge"><title>\\Firebird->\\DB_PDO</title>
|
||||||
<path fill="none" stroke="black" d="M755.815,-227.602C721.064,-223.258 667.487,-216.561 627.664,-211.583"/>
|
<path fill="none" stroke="black" d="M755.815,-236.398C721.064,-240.742 667.487,-247.439 627.664,-252.417"/>
|
||||||
<polygon fill="none" stroke="black" points="627.955,-208.092 617.598,-210.325 627.087,-215.038 627.955,-208.092"/>
|
<polygon fill="none" stroke="black" points="627.087,-248.962 617.598,-253.675 627.955,-255.908 627.087,-248.962"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Firebird_Util -->
|
<!-- \\Firebird_Util -->
|
||||||
<g id="node23" class="node"><title>\\Firebird_Util</title>
|
<g id="node23" class="node"><title>\\Firebird_Util</title>
|
||||||
@ -268,121 +268,128 @@
|
|||||||
</g>
|
</g>
|
||||||
<!-- \\Firebird_Util->\\DB_Util -->
|
<!-- \\Firebird_Util->\\DB_Util -->
|
||||||
<g id="edge35" class="edge"><title>\\Firebird_Util->\\DB_Util</title>
|
<g id="edge35" class="edge"><title>\\Firebird_Util->\\DB_Util</title>
|
||||||
<path fill="none" stroke="black" d="M750.892,-1023.95C744.548,-1021.01 738.078,-1017.96 732,-1015 692.965,-996.012 649.105,-973.262 617.686,-956.713"/>
|
<path fill="none" stroke="black" d="M738.988,-1029C705.13,-1020.53 661.125,-1009.53 627.225,-1001.06"/>
|
||||||
<polygon fill="none" stroke="black" points="619.24,-953.575 608.762,-952.003 615.972,-959.766 619.24,-953.575"/>
|
<polygon fill="none" stroke="black" points="628.051,-997.655 617.5,-998.625 626.353,-1004.45 628.051,-997.655"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Model -->
|
<!-- \\MM_Model -->
|
||||||
<g id="node24" class="node"><title>\\MM_Model</title>
|
<g id="node24" class="node"><title>\\MM_Model</title>
|
||||||
<a xlink:href="sys.model.html" xlink:title="MM_Model" target="_parent">
|
<a xlink:href="sys.core.model.html" xlink:title="MM_Model" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="610,-520 540,-520 540,-484 610,-484 610,-520"/>
|
<polygon fill="none" stroke="black" points="610,-574 540,-574 540,-538 610,-538 610,-574"/>
|
||||||
<text text-anchor="middle" x="575" y="-498.6" font-family="Courier,monospace" font-size="11.00">MM_Model</text>
|
<text text-anchor="middle" x="575" y="-552.6" font-family="Courier,monospace" font-size="11.00">MM_Model</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\miniMVC -->
|
<!-- \\miniMVC -->
|
||||||
<g id="node27" class="node"><title>\\miniMVC</title>
|
<g id="node27" class="node"><title>\\miniMVC</title>
|
||||||
<a xlink:href="sys.miniMVC.html" xlink:title="miniMVC" target="_parent">
|
<a xlink:href="sys.core.miniMVC.html" xlink:title="miniMVC" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="411,-466 347,-466 347,-430 411,-430 411,-466"/>
|
<polygon fill="none" stroke="black" points="411,-520 347,-520 347,-484 411,-484 411,-520"/>
|
||||||
<text text-anchor="middle" x="379" y="-444.6" font-family="Courier,monospace" font-size="11.00">miniMVC</text>
|
<text text-anchor="middle" x="379" y="-498.6" font-family="Courier,monospace" font-size="11.00">miniMVC</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Model->\\miniMVC -->
|
<!-- \\MM_Model->\\miniMVC -->
|
||||||
<g id="edge37" class="edge"><title>\\MM_Model->\\miniMVC</title>
|
<g id="edge37" class="edge"><title>\\MM_Model->\\miniMVC</title>
|
||||||
<path fill="none" stroke="black" d="M539.051,-492.096C505.958,-482.978 456.829,-469.443 421.74,-459.775"/>
|
<path fill="none" stroke="black" d="M539.051,-546.096C505.958,-536.978 456.829,-523.443 421.74,-513.775"/>
|
||||||
<polygon fill="none" stroke="black" points="422.359,-456.316 411.789,-457.034 420.5,-463.064 422.359,-456.316"/>
|
<polygon fill="none" stroke="black" points="422.359,-510.316 411.789,-511.034 420.5,-517.064 422.359,-510.316"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB -->
|
<!-- \\DB -->
|
||||||
<g id="node25" class="node"><title>\\DB</title>
|
<g id="node25" class="node"><title>\\DB</title>
|
||||||
<a xlink:href="sys.db.html" xlink:title="DB" target="_parent">
|
<a xlink:href="sys.core.db.html" xlink:title="DB" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="818,-466 764,-466 764,-430 818,-430 818,-466"/>
|
<polygon fill="none" stroke="black" points="818,-520 764,-520 764,-484 818,-484 818,-520"/>
|
||||||
<text text-anchor="middle" x="791" y="-444.6" font-family="Courier,monospace" font-size="11.00">DB</text>
|
<text text-anchor="middle" x="791" y="-498.6" font-family="Courier,monospace" font-size="11.00">DB</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\DB->\\Query_Builder -->
|
<!-- \\DB->\\Query_Builder -->
|
||||||
<g id="edge39" class="edge"><title>\\DB->\\Query_Builder</title>
|
<g id="edge39" class="edge"><title>\\DB->\\Query_Builder</title>
|
||||||
<path fill="none" stroke="black" d="M763.643,-448C732.077,-448 679.154,-448 637.385,-448"/>
|
<path fill="none" stroke="black" d="M763.643,-502C732.077,-502 679.154,-502 637.385,-502"/>
|
||||||
<polygon fill="none" stroke="black" points="637.298,-444.5 627.298,-448 637.298,-451.5 637.298,-444.5"/>
|
<polygon fill="none" stroke="black" points="637.298,-498.5 627.298,-502 637.298,-505.5 637.298,-498.5"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM -->
|
<!-- \\MM -->
|
||||||
<g id="node26" class="node"><title>\\MM</title>
|
<g id="node26" class="node"><title>\\MM</title>
|
||||||
<a xlink:href="sys.miniMVC.html" xlink:title="MM" target="_parent">
|
<a xlink:href="sys.core.miniMVC.html" xlink:title="MM" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="268,-520 214,-520 214,-484 268,-484 268,-520"/>
|
<polygon fill="none" stroke="black" points="268,-574 214,-574 214,-538 268,-538 268,-574"/>
|
||||||
<text text-anchor="middle" x="241" y="-498.6" font-family="Courier,monospace" font-size="11.00">MM</text>
|
<text text-anchor="middle" x="241" y="-552.6" font-family="Courier,monospace" font-size="11.00">MM</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\ArrayObject -->
|
<!-- \\ArrayObject -->
|
||||||
<g id="node55" class="node"><title>\\ArrayObject</title>
|
<g id="node56" class="node"><title>\\ArrayObject</title>
|
||||||
<ellipse fill="none" stroke="black" cx="71" cy="-502" rx="71.107" ry="18"/>
|
<ellipse fill="none" stroke="black" cx="71" cy="-556" rx="71.107" ry="18"/>
|
||||||
<text text-anchor="middle" x="71" y="-497.4" font-family="Times Roman,serif" font-size="14.00" fill="gray">\ArrayObject</text>
|
<text text-anchor="middle" x="71" y="-551.4" font-family="Times Roman,serif" font-size="14.00" fill="gray">\ArrayObject</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM->\\ArrayObject -->
|
<!-- \\MM->\\ArrayObject -->
|
||||||
<g id="edge41" class="edge"><title>\\MM->\\ArrayObject</title>
|
<g id="edge41" class="edge"><title>\\MM->\\ArrayObject</title>
|
||||||
<path fill="none" stroke="black" d="M213.687,-502C196.92,-502 174.483,-502 152.374,-502"/>
|
<path fill="none" stroke="black" d="M213.687,-556C196.92,-556 174.483,-556 152.374,-556"/>
|
||||||
<polygon fill="none" stroke="black" points="152.26,-498.5 142.26,-502 152.26,-505.5 152.26,-498.5"/>
|
<polygon fill="none" stroke="black" points="152.26,-552.5 142.26,-556 152.26,-559.5 152.26,-552.5"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\miniMVC->\\MM -->
|
<!-- \\miniMVC->\\MM -->
|
||||||
<g id="edge43" class="edge"><title>\\miniMVC->\\MM</title>
|
<g id="edge43" class="edge"><title>\\miniMVC->\\MM</title>
|
||||||
<path fill="none" stroke="black" d="M346.296,-460.797C325.699,-468.857 299.069,-479.277 277.744,-487.622"/>
|
<path fill="none" stroke="black" d="M346.296,-514.797C325.699,-522.857 299.069,-533.277 277.744,-541.622"/>
|
||||||
<polygon fill="none" stroke="black" points="276.397,-484.391 268.36,-491.294 278.948,-490.909 276.397,-484.391"/>
|
<polygon fill="none" stroke="black" points="276.397,-538.391 268.36,-545.294 278.948,-544.909 276.397,-538.391"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Page -->
|
<!-- \\MM_Page -->
|
||||||
<g id="node28" class="node"><title>\\MM_Page</title>
|
<g id="node28" class="node"><title>\\MM_Page</title>
|
||||||
<a xlink:href="sys.page.html" xlink:title="MM_Page" target="_parent">
|
<a xlink:href="sys.core.page.html" xlink:title="MM_Page" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="411,-574 347,-574 347,-538 411,-538 411,-574"/>
|
<polygon fill="none" stroke="black" points="411,-628 347,-628 347,-592 411,-592 411,-628"/>
|
||||||
<text text-anchor="middle" x="379" y="-552.6" font-family="Courier,monospace" font-size="11.00">MM_Page</text>
|
<text text-anchor="middle" x="379" y="-606.6" font-family="Courier,monospace" font-size="11.00">MM_Page</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Page->\\MM -->
|
<!-- \\MM_Page->\\MM -->
|
||||||
<g id="edge45" class="edge"><title>\\MM_Page->\\MM</title>
|
<g id="edge45" class="edge"><title>\\MM_Page->\\MM</title>
|
||||||
<path fill="none" stroke="black" d="M346.296,-543.203C325.699,-535.143 299.069,-524.723 277.744,-516.378"/>
|
<path fill="none" stroke="black" d="M346.296,-597.203C325.699,-589.143 299.069,-578.723 277.744,-570.378"/>
|
||||||
<polygon fill="none" stroke="black" points="278.948,-513.091 268.36,-512.706 276.397,-519.609 278.948,-513.091"/>
|
<polygon fill="none" stroke="black" points="278.948,-567.091 268.36,-566.706 276.397,-573.609 278.948,-567.091"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Controller -->
|
<!-- \\MM_Controller -->
|
||||||
<g id="node29" class="node"><title>\\MM_Controller</title>
|
<g id="node29" class="node"><title>\\MM_Controller</title>
|
||||||
<a xlink:href="sys.controller.html" xlink:title="MM_Controller" target="_parent">
|
<a xlink:href="sys.core.controller.html" xlink:title="MM_Controller" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="627,-412 523,-412 523,-376 627,-376 627,-412"/>
|
<polygon fill="none" stroke="black" points="627,-466 523,-466 523,-430 627,-430 627,-466"/>
|
||||||
<text text-anchor="middle" x="575" y="-390.6" font-family="Courier,monospace" font-size="11.00">MM_Controller</text>
|
<text text-anchor="middle" x="575" y="-444.6" font-family="Courier,monospace" font-size="11.00">MM_Controller</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Controller->\\miniMVC -->
|
<!-- \\MM_Controller->\\miniMVC -->
|
||||||
<g id="edge47" class="edge"><title>\\MM_Controller->\\miniMVC</title>
|
<g id="edge47" class="edge"><title>\\MM_Controller->\\miniMVC</title>
|
||||||
<path fill="none" stroke="black" d="M522.476,-408.471C490.93,-417.162 451.306,-428.079 421.696,-436.237"/>
|
<path fill="none" stroke="black" d="M522.476,-462.471C490.93,-471.162 451.306,-482.079 421.696,-490.237"/>
|
||||||
<polygon fill="none" stroke="black" points="420.381,-432.969 411.67,-438.999 422.24,-439.717 420.381,-432.969"/>
|
<polygon fill="none" stroke="black" points="420.381,-486.969 411.67,-492.999 422.24,-493.717 420.381,-486.969"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Output -->
|
<!-- \\MM_Output -->
|
||||||
<g id="node30" class="node"><title>\\MM_Output</title>
|
<g id="node30" class="node"><title>\\MM_Output</title>
|
||||||
<a xlink:href="sys.output.html" xlink:title="MM_Output" target="_parent">
|
<a xlink:href="sys.core.output.html" xlink:title="MM_Output" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="418,-520 340,-520 340,-484 418,-484 418,-520"/>
|
<polygon fill="none" stroke="black" points="418,-574 340,-574 340,-538 418,-538 418,-574"/>
|
||||||
<text text-anchor="middle" x="379" y="-498.6" font-family="Courier,monospace" font-size="11.00">MM_Output</text>
|
<text text-anchor="middle" x="379" y="-552.6" font-family="Courier,monospace" font-size="11.00">MM_Output</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\MM_Output->\\MM -->
|
<!-- \\MM_Output->\\MM -->
|
||||||
<g id="edge49" class="edge"><title>\\MM_Output->\\MM</title>
|
<g id="edge49" class="edge"><title>\\MM_Output->\\MM</title>
|
||||||
<path fill="none" stroke="black" d="M339.824,-502C320.46,-502 297.217,-502 278.137,-502"/>
|
<path fill="none" stroke="black" d="M339.824,-556C320.46,-556 297.217,-556 278.137,-556"/>
|
||||||
<polygon fill="none" stroke="black" points="278.018,-498.5 268.018,-502 278.017,-505.5 278.018,-498.5"/>
|
<polygon fill="none" stroke="black" points="278.018,-552.5 268.018,-556 278.017,-559.5 278.018,-552.5"/>
|
||||||
|
</g>
|
||||||
|
<!-- \\MM_Session -->
|
||||||
|
<g id="node31" class="node"><title>\\MM_Session</title>
|
||||||
|
<a xlink:href="sys.libraries.session.html" xlink:title="MM_Session" target="_parent">
|
||||||
|
<polygon fill="none" stroke="black" points="833,-196 749,-196 749,-160 833,-160 833,-196"/>
|
||||||
|
<text text-anchor="middle" x="791" y="-174.6" font-family="Courier,monospace" font-size="11.00">MM_Session</text>
|
||||||
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Welcome_Model -->
|
<!-- \\Welcome_Model -->
|
||||||
<g id="node31" class="node"><title>\\Welcome_Model</title>
|
<g id="node32" class="node"><title>\\Welcome_Model</title>
|
||||||
<a xlink:href="modules.welcome.models.welcome_model.html" xlink:title="Welcome_Model" target="_parent">
|
<a xlink:href="modules.welcome.models.welcome_model.html" xlink:title="Welcome_Model" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="843,-520 739,-520 739,-484 843,-484 843,-520"/>
|
<polygon fill="none" stroke="black" points="843,-574 739,-574 739,-538 843,-538 843,-574"/>
|
||||||
<text text-anchor="middle" x="791" y="-498.6" font-family="Courier,monospace" font-size="11.00">Welcome_Model</text>
|
<text text-anchor="middle" x="791" y="-552.6" font-family="Courier,monospace" font-size="11.00">Welcome_Model</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Welcome_Model->\\MM_Model -->
|
<!-- \\Welcome_Model->\\MM_Model -->
|
||||||
<g id="edge51" class="edge"><title>\\Welcome_Model->\\MM_Model</title>
|
<g id="edge51" class="edge"><title>\\Welcome_Model->\\MM_Model</title>
|
||||||
<path fill="none" stroke="black" d="M738.988,-502C703.013,-502 655.582,-502 620.988,-502"/>
|
<path fill="none" stroke="black" d="M738.988,-556C703.013,-556 655.582,-556 620.988,-556"/>
|
||||||
<polygon fill="none" stroke="black" points="620.692,-498.5 610.692,-502 620.692,-505.5 620.692,-498.5"/>
|
<polygon fill="none" stroke="black" points="620.692,-552.5 610.692,-556 620.692,-559.5 620.692,-552.5"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Welcome -->
|
<!-- \\Welcome -->
|
||||||
<g id="node32" class="node"><title>\\Welcome</title>
|
<g id="node33" class="node"><title>\\Welcome</title>
|
||||||
<a xlink:href="modules.welcome.controllers.welcome.html" xlink:title="Welcome" target="_parent">
|
<a xlink:href="modules.welcome.controllers.welcome.html" xlink:title="Welcome" target="_parent">
|
||||||
<polygon fill="none" stroke="black" points="823,-412 759,-412 759,-376 823,-376 823,-412"/>
|
<polygon fill="none" stroke="black" points="823,-466 759,-466 759,-430 823,-430 823,-466"/>
|
||||||
<text text-anchor="middle" x="791" y="-390.6" font-family="Courier,monospace" font-size="11.00">Welcome</text>
|
<text text-anchor="middle" x="791" y="-444.6" font-family="Courier,monospace" font-size="11.00">Welcome</text>
|
||||||
</a>
|
</a>
|
||||||
</g>
|
</g>
|
||||||
<!-- \\Welcome->\\MM_Controller -->
|
<!-- \\Welcome->\\MM_Controller -->
|
||||||
<g id="edge53" class="edge"><title>\\Welcome->\\MM_Controller</title>
|
<g id="edge53" class="edge"><title>\\Welcome->\\MM_Controller</title>
|
||||||
<path fill="none" stroke="black" d="M758.663,-394C726.833,-394 677.382,-394 637.808,-394"/>
|
<path fill="none" stroke="black" d="M758.663,-448C726.833,-448 677.382,-448 637.808,-448"/>
|
||||||
<polygon fill="none" stroke="black" points="637.717,-390.5 627.716,-394 637.716,-397.5 637.717,-390.5"/>
|
<polygon fill="none" stroke="black" points="637.717,-444.5 627.716,-448 637.716,-451.5 637.717,-444.5"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
@ -1583,7 +1583,7 @@ for complex select queries</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -679,7 +679,7 @@ the connection/database</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -152,7 +152,7 @@ and organizes database connections</p></p>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -269,7 +269,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -209,7 +209,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -833,7 +833,7 @@ the last query executed</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -504,7 +504,7 @@ the query</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -297,7 +297,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -212,7 +212,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -434,7 +434,7 @@ dynamic methods</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -368,7 +368,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
||||||
<h2>Method to load classes into the singleton</h2>
|
<h2>Method to load classes into the singleton</h2>
|
||||||
<pre>load_class(string $name, string $type) : void</pre>
|
<pre>load_class(string $name) : void</pre>
|
||||||
<div class="labels"><span class="label">Inherited</span></div>
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
<div class="row collapse"><div class="span8">
|
<div class="row collapse"><div class="span8">
|
||||||
<p class="long_description"></p>
|
<p class="long_description"></p>
|
||||||
@ -381,10 +381,6 @@
|
|||||||
<h4>$name</h4>
|
<h4>$name</h4>
|
||||||
<code>string</code>
|
<code>string</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="subelement argument">
|
|
||||||
<h4>$type</h4>
|
|
||||||
<code>string</code>
|
|
||||||
</div>
|
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
||||||
@ -764,7 +760,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -365,7 +365,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
||||||
<h2>Method to load classes into the singleton</h2>
|
<h2>Method to load classes into the singleton</h2>
|
||||||
<pre>load_class(string $name, string $type) : void</pre>
|
<pre>load_class(string $name) : void</pre>
|
||||||
<div class="labels"><span class="label">Inherited</span></div>
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
<div class="row collapse"><div class="span8">
|
<div class="row collapse"><div class="span8">
|
||||||
<p class="long_description"></p>
|
<p class="long_description"></p>
|
||||||
@ -378,10 +378,6 @@
|
|||||||
<h4>$name</h4>
|
<h4>$name</h4>
|
||||||
<code>string</code>
|
<code>string</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="subelement argument">
|
|
||||||
<h4>$type</h4>
|
|
||||||
<code>string</code>
|
|
||||||
</div>
|
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
||||||
@ -728,7 +724,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -640,7 +640,7 @@ Used for outputing HTML</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -972,7 +972,7 @@ supports</p></p>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
138
docs/classes/MM_Session.html
Normal file
138
docs/classes/MM_Session.html
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<!DOCTYPE html><html xmlns:date="http://exslt.org/dates-and-times" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>miniMVC » \MM_Session</title>
|
||||||
|
<meta name="author" content="Mike van Riel">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<link href="../css/template.css" rel="stylesheet" media="all">
|
||||||
|
<script src="../js/jquery-1.7.1.min.js" type="text/javascript"></script><script src="../js/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script><script src="../js/jquery.mousewheel.min.js" type="text/javascript"></script><script src="../js/bootstrap.js" type="text/javascript"></script><script src="../js/template.js" type="text/javascript"></script><script src="../js/prettify/prettify.min.js" type="text/javascript"></script><link rel="shortcut icon" href="../img/favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" href="../img/apple-touch-icon.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="../img/apple-touch-icon-72x72.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="../img/apple-touch-icon-114x114.png">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="navbar navbar-fixed-top">
|
||||||
|
<div class="navbar-inner"><div class="container">
|
||||||
|
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></a><a class="brand" href="../index.html">miniMVC</a><div class="nav-collapse"><ul class="nav">
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#api" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
API Documentation <b class="caret"></b></a><ul class="dropdown-menu">
|
||||||
|
<li><a>Packages</a></li>
|
||||||
|
<li><a href="../packages/Default.html"><i class="icon-folder-open"></i> Default</a></li>
|
||||||
|
<li><a href="../packages/Query.html"><i class="icon-folder-open"></i> Query</a></li>
|
||||||
|
<li><a href="../packages/miniMVC.html"><i class="icon-folder-open"></i> miniMVC</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown" id="charts-menu">
|
||||||
|
<a href="#charts" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Charts <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="../graph_class.html"><i class="icon-list-alt"></i> Class hierarchy diagram</a></li></ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown" id="reports-menu">
|
||||||
|
<a href="#reports" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Reports <b class="caret"></b></a><ul class="dropdown-menu">
|
||||||
|
<li><a href="../errors.html"><i class="icon-remove-sign"></i> Errors
|
||||||
|
<span class="label label-info">0</span></a></li>
|
||||||
|
<li><a href="../markers.html"><i class="icon-map-marker"></i> Markers
|
||||||
|
<ul></ul></a></li>
|
||||||
|
<li><a href="../deprecated.html"><i class="icon-stop"></i> Deprecated elements
|
||||||
|
<span class="label label-info">0</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul></div>
|
||||||
|
</div></div>
|
||||||
|
<div class="go_to_top"><a href="#___" style="color: inherit">Back to top <i class="icon-upload icon-white"></i></a></div>
|
||||||
|
</div>
|
||||||
|
<div id="___" class="container">
|
||||||
|
<noscript><div class="alert alert-warning">
|
||||||
|
Javascript is disabled; several features are only available
|
||||||
|
if Javascript is enabled.
|
||||||
|
</div></noscript>
|
||||||
|
<div class="row">
|
||||||
|
<div class="span4">
|
||||||
|
<span class="btn-group visibility" data-toggle="buttons-checkbox"><button class="btn public active" title="Show public elements">Public</button><button class="btn protected" title="Show protected elements">Protected</button><button class="btn private" title="Show private elements">Private</button><button class="btn inherited active" title="Show inherited elements">Inherited</button></span><div class="btn-group view pull-right" data-toggle="buttons-radio">
|
||||||
|
<button class="btn details" title="Show descriptions and method names"><i class="icon-list"></i></button><button class="btn simple" title="Show only method names"><i class="icon-align-justify"></i></button>
|
||||||
|
</div>
|
||||||
|
<ul class="side-nav nav nav-list">
|
||||||
|
<li class="nav-header">
|
||||||
|
<i class="icon-custom icon-method"></i> Methods</li>
|
||||||
|
<li class="method public "><a href="#__get" title="__get :: Retreive a session value"><span class="description">Retreive a session value</span><pre>__get()</pre></a></li>
|
||||||
|
<li class="method public "><a href="#__set" title="__set :: Set a session value"><span class="description">Set a session value</span><pre>__set()</pre></a></li>
|
||||||
|
<li class="method public "><a href="#destroy" title="destroy :: Destroy a session"><span class="description">Destroy a session</span><pre>destroy()</pre></a></li>
|
||||||
|
<li class="nav-header protected">» Protected</li>
|
||||||
|
<li class="method protected "><a href="#__construct" title="__construct :: Start a session"><span class="description">Start a session</span><pre>__construct()</pre></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="span8">
|
||||||
|
<a name="%5CMM_Session" id="\MM_Session"></a><div href="../classes/MM_Session.html" class="element class">
|
||||||
|
<p class="short_description">Class to improve handling of PHP sessions</p>
|
||||||
|
<div class="details">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>package</th>
|
||||||
|
<td><a href="..//packages/miniMVC.Libraries.html">miniMVC</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>subpackage</th>
|
||||||
|
<td>Libraries</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>
|
||||||
|
<i class="icon-custom icon-method"></i> Methods</h3>
|
||||||
|
<a name="__get" id="__get"></a><div class="element clickable method public __get" data-toggle="collapse" data-target=".__get .collapse">
|
||||||
|
<h2>Retreive a session value</h2>
|
||||||
|
<pre>__get(string $key) : mixed</pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<h3>Parameters</h3>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$key</h4>
|
||||||
|
<code>string</code>
|
||||||
|
</div>
|
||||||
|
<h3>Returns</h3>
|
||||||
|
<div class="subelement response"><code>mixed</code></div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="__set" id="__set"></a><div class="element clickable method public __set" data-toggle="collapse" data-target=".__set .collapse">
|
||||||
|
<h2>Set a session value</h2>
|
||||||
|
<pre>__set(string $key, mixed $val) : void</pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<h3>Parameters</h3>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$key</h4>
|
||||||
|
<code>string</code>
|
||||||
|
</div>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$val</h4>
|
||||||
|
<code>mixed</code>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="destroy" id="destroy"></a><div class="element clickable method public destroy" data-toggle="collapse" data-target=".destroy .collapse">
|
||||||
|
<h2>Destroy a session</h2>
|
||||||
|
<pre>destroy() : void</pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8"><p class="long_description"></p></div></div>
|
||||||
|
</div>
|
||||||
|
<a name="__construct" id="__construct"></a><div class="element clickable method protected __construct" data-toggle="collapse" data-target=".__construct .collapse">
|
||||||
|
<h2>Start a session</h2>
|
||||||
|
<pre>__construct() </pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8"><p class="long_description"></p></div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row"><footer class="span12">
|
||||||
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -869,7 +869,7 @@ the connection/database</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -281,7 +281,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -208,7 +208,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -871,7 +871,7 @@ the connection/database</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -281,7 +281,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -203,7 +203,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
633
docs/classes/PHP_Session.html
Normal file
633
docs/classes/PHP_Session.html
Normal file
@ -0,0 +1,633 @@
|
|||||||
|
<!DOCTYPE html><html xmlns:date="http://exslt.org/dates-and-times" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>miniMVC » \PHP_Session</title>
|
||||||
|
<meta name="author" content="Mike van Riel">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<link href="../css/template.css" rel="stylesheet" media="all">
|
||||||
|
<script src="../js/jquery-1.7.1.min.js" type="text/javascript"></script><script src="../js/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script><script src="../js/jquery.mousewheel.min.js" type="text/javascript"></script><script src="../js/bootstrap.js" type="text/javascript"></script><script src="../js/template.js" type="text/javascript"></script><script src="../js/prettify/prettify.min.js" type="text/javascript"></script><link rel="shortcut icon" href="../img/favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" href="../img/apple-touch-icon.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="../img/apple-touch-icon-72x72.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="../img/apple-touch-icon-114x114.png">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="navbar navbar-fixed-top">
|
||||||
|
<div class="navbar-inner"><div class="container">
|
||||||
|
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></a><a class="brand" href="../index.html">miniMVC</a><div class="nav-collapse"><ul class="nav">
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#api" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
API Documentation <b class="caret"></b></a><ul class="dropdown-menu">
|
||||||
|
<li><a>Packages</a></li>
|
||||||
|
<li><a href="../packages/Default.html"><i class="icon-folder-open"></i> Default</a></li>
|
||||||
|
<li><a href="../packages/Query.html"><i class="icon-folder-open"></i> Query</a></li>
|
||||||
|
<li><a href="../packages/miniMVC.html"><i class="icon-folder-open"></i> miniMVC</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown" id="charts-menu">
|
||||||
|
<a href="#charts" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Charts <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="../graph_class.html"><i class="icon-list-alt"></i> Class hierarchy diagram</a></li></ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown" id="reports-menu">
|
||||||
|
<a href="#reports" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Reports <b class="caret"></b></a><ul class="dropdown-menu">
|
||||||
|
<li><a href="../errors.html"><i class="icon-remove-sign"></i> Errors
|
||||||
|
<span class="label label-info">0</span></a></li>
|
||||||
|
<li><a href="../markers.html"><i class="icon-map-marker"></i> Markers
|
||||||
|
<ul></ul></a></li>
|
||||||
|
<li><a href="../deprecated.html"><i class="icon-stop"></i> Deprecated elements
|
||||||
|
<span class="label label-info">0</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul></div>
|
||||||
|
</div></div>
|
||||||
|
<div class="go_to_top"><a href="#___" style="color: inherit">Back to top <i class="icon-upload icon-white"></i></a></div>
|
||||||
|
</div>
|
||||||
|
<div id="___" class="container">
|
||||||
|
<noscript><div class="alert alert-warning">
|
||||||
|
Javascript is disabled; several features are only available
|
||||||
|
if Javascript is enabled.
|
||||||
|
</div></noscript>
|
||||||
|
<div class="row">
|
||||||
|
<div class="span4">
|
||||||
|
<span class="btn-group visibility" data-toggle="buttons-checkbox"><button class="btn public active" title="Show public elements">Public</button><button class="btn protected" title="Show protected elements">Protected</button><button class="btn private" title="Show private elements">Private</button><button class="btn inherited active" title="Show inherited elements">Inherited</button></span><div class="btn-group view pull-right" data-toggle="buttons-radio">
|
||||||
|
<button class="btn details" title="Show descriptions and method names"><i class="icon-list"></i></button><button class="btn simple" title="Show only method names"><i class="icon-align-justify"></i></button>
|
||||||
|
</div>
|
||||||
|
<ul class="side-nav nav nav-list">
|
||||||
|
<li class="nav-header">
|
||||||
|
<i class="icon-custom icon-method"></i> Methods</li>
|
||||||
|
<li class="method public inherited"><a href="#__call" title="__call :: Allow calling of array methods on the object and
|
||||||
|
dynamic methods"><span class="description">Allow calling of array methods on the object and
|
||||||
|
dynamic methods</span><pre>__call()</pre></a></li>
|
||||||
|
<li class="method public "><a href="#__get" title="__get :: Retreive a session value"><span class="description">Retreive a session value</span><pre>__get()</pre></a></li>
|
||||||
|
<li class="method public "><a href="#__set" title="__set :: Set a session value"><span class="description">Set a session value</span><pre>__set()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#append" title="append :: "><span class="description">append()
|
||||||
|
</span><pre>append()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#asort" title="asort :: "><span class="description">asort()
|
||||||
|
</span><pre>asort()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#count" title="count :: "><span class="description">count()
|
||||||
|
</span><pre>count()</pre></a></li>
|
||||||
|
<li class="method public "><a href="#destroy" title="destroy :: Destroy a session"><span class="description">Destroy a session</span><pre>destroy()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#exchangeArray" title="exchangeArray :: "><span class="description">exchangeArray()
|
||||||
|
</span><pre>exchangeArray()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#getArrayCopy" title="getArrayCopy :: "><span class="description">getArrayCopy()
|
||||||
|
</span><pre>getArrayCopy()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#getFlags" title="getFlags :: "><span class="description">getFlags()
|
||||||
|
</span><pre>getFlags()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#getIterator" title="getIterator :: "><span class="description">getIterator()
|
||||||
|
</span><pre>getIterator()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#getIteratorClass" title="getIteratorClass :: "><span class="description">getIteratorClass()
|
||||||
|
</span><pre>getIteratorClass()</pre></a></li>
|
||||||
|
<li class="method public "><a href="#get_instance" title="get_instance :: Return or create singleton"><span class="description">Return or create singleton</span><pre>get_instance()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#ksort" title="ksort :: "><span class="description">ksort()
|
||||||
|
</span><pre>ksort()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#natcasesort" title="natcasesort :: "><span class="description">natcasesort()
|
||||||
|
</span><pre>natcasesort()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#natsort" title="natsort :: "><span class="description">natsort()
|
||||||
|
</span><pre>natsort()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#offsetExists" title="offsetExists :: "><span class="description">offsetExists()
|
||||||
|
</span><pre>offsetExists()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#offsetGet" title="offsetGet :: "><span class="description">offsetGet()
|
||||||
|
</span><pre>offsetGet()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#offsetSet" title="offsetSet :: "><span class="description">offsetSet()
|
||||||
|
</span><pre>offsetSet()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#offsetUnset" title="offsetUnset :: "><span class="description">offsetUnset()
|
||||||
|
</span><pre>offsetUnset()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#serialize" title="serialize :: "><span class="description">serialize()
|
||||||
|
</span><pre>serialize()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#setFlags" title="setFlags :: "><span class="description">setFlags()
|
||||||
|
</span><pre>setFlags()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#setIteratorClass" title="setIteratorClass :: "><span class="description">setIteratorClass()
|
||||||
|
</span><pre>setIteratorClass()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#uasort" title="uasort :: "><span class="description">uasort()
|
||||||
|
</span><pre>uasort()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#uksort" title="uksort :: "><span class="description">uksort()
|
||||||
|
</span><pre>uksort()</pre></a></li>
|
||||||
|
<li class="method public inherited"><a href="#unserialize" title="unserialize :: "><span class="description">unserialize()
|
||||||
|
</span><pre>unserialize()</pre></a></li>
|
||||||
|
<li class="nav-header protected">» Protected</li>
|
||||||
|
<li class="method protected "><a href="#__construct" title="__construct :: Start a session"><span class="description">Start a session</span><pre>__construct()</pre></a></li>
|
||||||
|
<li class="nav-header">
|
||||||
|
<i class="icon-custom icon-property"></i> Properties</li>
|
||||||
|
<li class="nav-header protected">» Protected</li>
|
||||||
|
<li class="property protected "><a href="#%24instance" title="$instance :: Instance of the current class"><span class="description">Instance of the current class</span><pre>$instance</pre></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="span8">
|
||||||
|
<a name="%5CPHP_Session" id="\PHP_Session"></a><div href="../classes/PHP_Session.html" class="element class">
|
||||||
|
<p class="short_description">Class to improve handling of PHP sessions</p>
|
||||||
|
<div class="details">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>package</th>
|
||||||
|
<td><a href="..//packages/miniMVC.Libraries.html">miniMVC</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>subpackage</th>
|
||||||
|
<td>Libraries</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>
|
||||||
|
<i class="icon-custom icon-method"></i> Methods</h3>
|
||||||
|
<a name="__call" id="__call"></a><div class="element clickable method public __call" data-toggle="collapse" data-target=".__call .collapse">
|
||||||
|
<h2>Allow calling of array methods on the object and
|
||||||
|
dynamic methods</h2>
|
||||||
|
<pre>__call(string $name, array $params) : mixed</pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered"><tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::__call()</td>
|
||||||
|
</tr></table>
|
||||||
|
<h3>Parameters</h3>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$name</h4>
|
||||||
|
<code>string</code>
|
||||||
|
</div>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$params</h4>
|
||||||
|
<code>array</code>
|
||||||
|
</div>
|
||||||
|
<h3>Returns</h3>
|
||||||
|
<div class="subelement response"><code>mixed</code></div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="__get" id="__get"></a><div class="element clickable method public __get" data-toggle="collapse" data-target=".__get .collapse">
|
||||||
|
<h2>Retreive a session value</h2>
|
||||||
|
<pre>__get(string $key) : mixed</pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<h3>Parameters</h3>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$key</h4>
|
||||||
|
<code>string</code>
|
||||||
|
</div>
|
||||||
|
<h3>Returns</h3>
|
||||||
|
<div class="subelement response"><code>mixed</code></div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="__set" id="__set"></a><div class="element clickable method public __set" data-toggle="collapse" data-target=".__set .collapse">
|
||||||
|
<h2>Set a session value</h2>
|
||||||
|
<pre>__set(string $key, mixed $val) : void</pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<h3>Parameters</h3>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$key</h4>
|
||||||
|
<code>string</code>
|
||||||
|
</div>
|
||||||
|
<div class="subelement argument">
|
||||||
|
<h4>$val</h4>
|
||||||
|
<code>mixed</code>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="append" id="append"></a><div class="element clickable method public append" data-toggle="collapse" data-target=".append .collapse">
|
||||||
|
<h2>append()
|
||||||
|
</h2>
|
||||||
|
<pre>append() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::append()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::append()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="asort" id="asort"></a><div class="element clickable method public asort" data-toggle="collapse" data-target=".asort .collapse">
|
||||||
|
<h2>asort()
|
||||||
|
</h2>
|
||||||
|
<pre>asort() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::asort()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::asort()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="count" id="count"></a><div class="element clickable method public count" data-toggle="collapse" data-target=".count .collapse">
|
||||||
|
<h2>count()
|
||||||
|
</h2>
|
||||||
|
<pre>count() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::count()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::count()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="destroy" id="destroy"></a><div class="element clickable method public destroy" data-toggle="collapse" data-target=".destroy .collapse">
|
||||||
|
<h2>Destroy a session</h2>
|
||||||
|
<pre>destroy() : void</pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8"><p class="long_description"></p></div></div>
|
||||||
|
</div>
|
||||||
|
<a name="exchangeArray" id="exchangeArray"></a><div class="element clickable method public exchangeArray" data-toggle="collapse" data-target=".exchangeArray .collapse">
|
||||||
|
<h2>exchangeArray()
|
||||||
|
</h2>
|
||||||
|
<pre>exchangeArray() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::exchangeArray()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::exchangeArray()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="getArrayCopy" id="getArrayCopy"></a><div class="element clickable method public getArrayCopy" data-toggle="collapse" data-target=".getArrayCopy .collapse">
|
||||||
|
<h2>getArrayCopy()
|
||||||
|
</h2>
|
||||||
|
<pre>getArrayCopy() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::getArrayCopy()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::getArrayCopy()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="getFlags" id="getFlags"></a><div class="element clickable method public getFlags" data-toggle="collapse" data-target=".getFlags .collapse">
|
||||||
|
<h2>getFlags()
|
||||||
|
</h2>
|
||||||
|
<pre>getFlags() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::getFlags()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::getFlags()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="getIterator" id="getIterator"></a><div class="element clickable method public getIterator" data-toggle="collapse" data-target=".getIterator .collapse">
|
||||||
|
<h2>getIterator()
|
||||||
|
</h2>
|
||||||
|
<pre>getIterator() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::getIterator()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::getIterator()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="getIteratorClass" id="getIteratorClass"></a><div class="element clickable method public getIteratorClass" data-toggle="collapse" data-target=".getIteratorClass .collapse">
|
||||||
|
<h2>getIteratorClass()
|
||||||
|
</h2>
|
||||||
|
<pre>getIteratorClass() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::getIteratorClass()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::getIteratorClass()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="get_instance" id="get_instance"></a><div class="element clickable method public get_instance" data-toggle="collapse" data-target=".get_instance .collapse">
|
||||||
|
<h2>Return or create singleton</h2>
|
||||||
|
<pre>get_instance() : <a href="../classes/PHP_Session.html">\PHP_Session</a></pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered"><tr>
|
||||||
|
<th>fluent</th>
|
||||||
|
<td>This method is part of a fluent interface and will return the same instance</td>
|
||||||
|
</tr></table>
|
||||||
|
<h3>Returns</h3>
|
||||||
|
<div class="subelement response"><code><a href="../classes/PHP_Session.html">\PHP_Session</a></code></div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="ksort" id="ksort"></a><div class="element clickable method public ksort" data-toggle="collapse" data-target=".ksort .collapse">
|
||||||
|
<h2>ksort()
|
||||||
|
</h2>
|
||||||
|
<pre>ksort() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::ksort()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::ksort()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="natcasesort" id="natcasesort"></a><div class="element clickable method public natcasesort" data-toggle="collapse" data-target=".natcasesort .collapse">
|
||||||
|
<h2>natcasesort()
|
||||||
|
</h2>
|
||||||
|
<pre>natcasesort() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::natcasesort()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::natcasesort()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="natsort" id="natsort"></a><div class="element clickable method public natsort" data-toggle="collapse" data-target=".natsort .collapse">
|
||||||
|
<h2>natsort()
|
||||||
|
</h2>
|
||||||
|
<pre>natsort() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::natsort()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::natsort()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="offsetExists" id="offsetExists"></a><div class="element clickable method public offsetExists" data-toggle="collapse" data-target=".offsetExists .collapse">
|
||||||
|
<h2>offsetExists()
|
||||||
|
</h2>
|
||||||
|
<pre>offsetExists() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::offsetExists()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::offsetExists()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="offsetGet" id="offsetGet"></a><div class="element clickable method public offsetGet" data-toggle="collapse" data-target=".offsetGet .collapse">
|
||||||
|
<h2>offsetGet()
|
||||||
|
</h2>
|
||||||
|
<pre>offsetGet() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::offsetGet()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::offsetGet()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="offsetSet" id="offsetSet"></a><div class="element clickable method public offsetSet" data-toggle="collapse" data-target=".offsetSet .collapse">
|
||||||
|
<h2>offsetSet()
|
||||||
|
</h2>
|
||||||
|
<pre>offsetSet() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::offsetSet()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::offsetSet()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="offsetUnset" id="offsetUnset"></a><div class="element clickable method public offsetUnset" data-toggle="collapse" data-target=".offsetUnset .collapse">
|
||||||
|
<h2>offsetUnset()
|
||||||
|
</h2>
|
||||||
|
<pre>offsetUnset() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::offsetUnset()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::offsetUnset()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="serialize" id="serialize"></a><div class="element clickable method public serialize" data-toggle="collapse" data-target=".serialize .collapse">
|
||||||
|
<h2>serialize()
|
||||||
|
</h2>
|
||||||
|
<pre>serialize() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::serialize()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::serialize()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="setFlags" id="setFlags"></a><div class="element clickable method public setFlags" data-toggle="collapse" data-target=".setFlags .collapse">
|
||||||
|
<h2>setFlags()
|
||||||
|
</h2>
|
||||||
|
<pre>setFlags() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::setFlags()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::setFlags()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="setIteratorClass" id="setIteratorClass"></a><div class="element clickable method public setIteratorClass" data-toggle="collapse" data-target=".setIteratorClass .collapse">
|
||||||
|
<h2>setIteratorClass()
|
||||||
|
</h2>
|
||||||
|
<pre>setIteratorClass() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::setIteratorClass()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::setIteratorClass()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="uasort" id="uasort"></a><div class="element clickable method public uasort" data-toggle="collapse" data-target=".uasort .collapse">
|
||||||
|
<h2>uasort()
|
||||||
|
</h2>
|
||||||
|
<pre>uasort() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::uasort()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::uasort()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="uksort" id="uksort"></a><div class="element clickable method public uksort" data-toggle="collapse" data-target=".uksort .collapse">
|
||||||
|
<h2>uksort()
|
||||||
|
</h2>
|
||||||
|
<pre>uksort() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::uksort()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::uksort()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="unserialize" id="unserialize"></a><div class="element clickable method public unserialize" data-toggle="collapse" data-target=".unserialize .collapse">
|
||||||
|
<h2>unserialize()
|
||||||
|
</h2>
|
||||||
|
<pre>unserialize() </pre>
|
||||||
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
|
<div class="row collapse"><div class="span8">
|
||||||
|
<p class="long_description"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>ArrayObject::unserialize()</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>inherited_from</th>
|
||||||
|
<td>\MM::unserialize()</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<a name="__construct" id="__construct"></a><div class="element clickable method protected __construct" data-toggle="collapse" data-target=".__construct .collapse">
|
||||||
|
<h2>Start a session</h2>
|
||||||
|
<pre>__construct() </pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8"><p class="long_description"></p></div></div>
|
||||||
|
</div>
|
||||||
|
<h3>
|
||||||
|
<i class="icon-custom icon-property"></i> Properties</h3>
|
||||||
|
<a name="%24instance" id="$instance"> </a><div class="element clickable property protected $instance" data-toggle="collapse" data-target=".$instance .collapse">
|
||||||
|
<h2>Instance of the current class</h2>
|
||||||
|
<pre>$instance : <a href="../classes/PHP_Session.html">\PHP_Session</a></pre>
|
||||||
|
<div class="labels"></div>
|
||||||
|
<div class="row collapse"><div class="span8"><p class="long_description"></p></div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row"><footer class="span12">
|
||||||
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
|
generated on 2012-05-03T12:48:51-04:00.<br></footer></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -871,7 +871,7 @@ the connection/database</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -297,7 +297,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -208,7 +208,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1222,7 +1222,7 @@ for complex select queries</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -886,7 +886,7 @@ method if the database does not support 'TRUNCATE';</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -281,7 +281,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -208,7 +208,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -244,7 +244,7 @@ directly - the settings should be safe!</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -418,7 +418,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
||||||
<h2>Method to load classes into the singleton</h2>
|
<h2>Method to load classes into the singleton</h2>
|
||||||
<pre>load_class(string $name, string $type) : void</pre>
|
<pre>load_class(string $name) : void</pre>
|
||||||
<div class="labels"><span class="label">Inherited</span></div>
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
<div class="row collapse"><div class="span8">
|
<div class="row collapse"><div class="span8">
|
||||||
<p class="long_description"></p>
|
<p class="long_description"></p>
|
||||||
@ -437,10 +437,6 @@
|
|||||||
<h4>$name</h4>
|
<h4>$name</h4>
|
||||||
<code>string</code>
|
<code>string</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="subelement argument">
|
|
||||||
<h4>$type</h4>
|
|
||||||
<code>string</code>
|
|
||||||
</div>
|
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
||||||
@ -906,7 +902,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -407,7 +407,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
||||||
<h2>Method to load classes into the singleton</h2>
|
<h2>Method to load classes into the singleton</h2>
|
||||||
<pre>load_class(string $name, string $type) : void</pre>
|
<pre>load_class(string $name) : void</pre>
|
||||||
<div class="labels"><span class="label">Inherited</span></div>
|
<div class="labels"><span class="label">Inherited</span></div>
|
||||||
<div class="row collapse"><div class="span8">
|
<div class="row collapse"><div class="span8">
|
||||||
<p class="long_description"></p>
|
<p class="long_description"></p>
|
||||||
@ -426,10 +426,6 @@
|
|||||||
<h4>$name</h4>
|
<h4>$name</h4>
|
||||||
<code>string</code>
|
<code>string</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="subelement argument">
|
|
||||||
<h4>$type</h4>
|
|
||||||
<code>string</code>
|
|
||||||
</div>
|
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
||||||
@ -846,7 +842,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -331,7 +331,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
<a name="load_class" id="load_class"></a><div class="element clickable method public load_class" data-toggle="collapse" data-target=".load_class .collapse">
|
||||||
<h2>Method to load classes into the singleton</h2>
|
<h2>Method to load classes into the singleton</h2>
|
||||||
<pre>load_class(string $name, string $type) : void</pre>
|
<pre>load_class(string $name) : void</pre>
|
||||||
<div class="labels"></div>
|
<div class="labels"></div>
|
||||||
<div class="row collapse"><div class="span8">
|
<div class="row collapse"><div class="span8">
|
||||||
<p class="long_description"></p>
|
<p class="long_description"></p>
|
||||||
@ -340,10 +340,6 @@
|
|||||||
<h4>$name</h4>
|
<h4>$name</h4>
|
||||||
<code>string</code>
|
<code>string</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="subelement argument">
|
|
||||||
<h4>$type</h4>
|
|
||||||
<code>string</code>
|
|
||||||
</div>
|
|
||||||
</div></div>
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
<a name="load_config" id="load_config"></a><div class="element clickable method public load_config" data-toggle="collapse" data-target=".load_config .collapse">
|
||||||
@ -615,7 +611,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -101,12 +101,13 @@
|
|||||||
<div class="package-contents"></div>
|
<div class="package-contents"></div>
|
||||||
<div class="package-contents"></div>
|
<div class="package-contents"></div>
|
||||||
<div class="package-contents"></div>
|
<div class="package-contents"></div>
|
||||||
|
<div class="package-contents"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
</script><div class="row"><footer class="span12">
|
</script><div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -448,6 +448,13 @@ data-fetching methods</p>
|
|||||||
<div class="details collapse"></div>
|
<div class="details collapse"></div>
|
||||||
<a href="../classes/MM_Page.html" class="more">« More »</a>
|
<a href="../classes/MM_Page.html" class="more">« More »</a>
|
||||||
</div>
|
</div>
|
||||||
|
<a name="MM_Session" id="MM_Session"></a><div class="element ajax clickable class" href="../classes/MM_Session.html">
|
||||||
|
<h1>MM_Session<a href="../classes/MM_Session.html">¶</a>
|
||||||
|
</h1>
|
||||||
|
<p class="short_description">Class to improve handling of PHP sessions</p>
|
||||||
|
<div class="details collapse"></div>
|
||||||
|
<a href="../classes/MM_Session.html" class="more">« More »</a>
|
||||||
|
</div>
|
||||||
<a name="MySQL" id="MySQL"></a><div class="element ajax clickable class" href="../classes/MySQL.html">
|
<a name="MySQL" id="MySQL"></a><div class="element ajax clickable class" href="../classes/MySQL.html">
|
||||||
<h1>MySQL<a href="../classes/MySQL.html">¶</a>
|
<h1>MySQL<a href="../classes/MySQL.html">¶</a>
|
||||||
</h1>
|
</h1>
|
||||||
@ -702,7 +709,7 @@ instantiates the specific db driver</p>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -185,7 +185,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -211,7 +211,7 @@ data-fetching methods</p>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -115,7 +115,7 @@ instantiates the specific db driver</p>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -316,7 +316,7 @@ instantiates the specific db driver</p>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -139,7 +139,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
95
docs/packages/miniMVC.Libraries.html
Normal file
95
docs/packages/miniMVC.Libraries.html
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE html><html xmlns:date="http://exslt.org/dates-and-times" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>miniMVC » miniMVC\Libraries</title>
|
||||||
|
<meta name="author" content="Mike van Riel">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<link href="../css/template.css" rel="stylesheet" media="all">
|
||||||
|
<script src="../js/jquery-1.7.1.min.js" type="text/javascript"></script><script src="../js/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script><script src="../js/jquery.mousewheel.min.js" type="text/javascript"></script><script src="../js/bootstrap.js" type="text/javascript"></script><script src="../js/template.js" type="text/javascript"></script><script src="../js/prettify/prettify.min.js" type="text/javascript"></script><link rel="shortcut icon" href="../img/favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" href="../img/apple-touch-icon.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="../img/apple-touch-icon-72x72.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="../img/apple-touch-icon-114x114.png">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="navbar navbar-fixed-top">
|
||||||
|
<div class="navbar-inner"><div class="container">
|
||||||
|
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></a><a class="brand" href="../index.html">miniMVC</a><div class="nav-collapse"><ul class="nav">
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#api" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
API Documentation <b class="caret"></b></a><ul class="dropdown-menu">
|
||||||
|
<li><a>Packages</a></li>
|
||||||
|
<li><a href="../packages/Default.html"><i class="icon-folder-open"></i> Default</a></li>
|
||||||
|
<li><a href="../packages/Query.html"><i class="icon-folder-open"></i> Query</a></li>
|
||||||
|
<li><a href="../packages/miniMVC.html"><i class="icon-folder-open"></i> miniMVC</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown" id="charts-menu">
|
||||||
|
<a href="#charts" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Charts <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="../graph_class.html"><i class="icon-list-alt"></i> Class hierarchy diagram</a></li></ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown" id="reports-menu">
|
||||||
|
<a href="#reports" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Reports <b class="caret"></b></a><ul class="dropdown-menu">
|
||||||
|
<li><a href="../errors.html"><i class="icon-remove-sign"></i> Errors
|
||||||
|
<span class="label label-info">0</span></a></li>
|
||||||
|
<li><a href="../markers.html"><i class="icon-map-marker"></i> Markers
|
||||||
|
<ul></ul></a></li>
|
||||||
|
<li><a href="../deprecated.html"><i class="icon-stop"></i> Deprecated elements
|
||||||
|
<span class="label label-info">0</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul></div>
|
||||||
|
</div></div>
|
||||||
|
<div class="go_to_top"><a href="#___" style="color: inherit">Back to top <i class="icon-upload icon-white"></i></a></div>
|
||||||
|
</div>
|
||||||
|
<div id="___" class="container">
|
||||||
|
<noscript><div class="alert alert-warning">
|
||||||
|
Javascript is disabled; several features are only available
|
||||||
|
if Javascript is enabled.
|
||||||
|
</div></noscript>
|
||||||
|
<div class="row">
|
||||||
|
<div class="span4">
|
||||||
|
<div class="btn-group view pull-right" data-toggle="buttons-radio">
|
||||||
|
<button class="btn details" title="Show descriptions and method names"><i class="icon-list"></i></button><button class="btn simple" title="Show only method names"><i class="icon-align-justify"></i></button>
|
||||||
|
</div>
|
||||||
|
<ul class="side-nav nav nav-list">
|
||||||
|
<li class="nav-header">
|
||||||
|
<i class="icon-map-marker"></i> Packages</li>
|
||||||
|
<li>
|
||||||
|
<a href="../packages/miniMVC.Libraries.html" title="Libraries"><i class="icon-folder-open"></i>Libraries</a><ul class="nav nav-list nav-packages"></ul>
|
||||||
|
</li>
|
||||||
|
<li class="nav-header">
|
||||||
|
<i class="icon-custom icon-class"></i> Classes</li>
|
||||||
|
<li><a href="#MM_Session" title="Class to improve handling of PHP sessions">MM_Session</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="span8 package-contents">
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
<li>
|
||||||
|
<a href="../index.html"><i class="icon-folder-open"></i></a><span class="divider">\</span>
|
||||||
|
</li>
|
||||||
|
<li><a href="../packages/miniMVC.html">miniMVC</a></li>
|
||||||
|
<span class="divider">\</span><li class="active"><a href="../packages/miniMVC.Libraries.html">Libraries</a></li>
|
||||||
|
</ul>
|
||||||
|
<div class="package-indent">
|
||||||
|
<h3>
|
||||||
|
<i class="icon-custom icon-class"></i> Classes and interfaces</h3>
|
||||||
|
<a name="MM_Session" id="MM_Session"></a><div class="element ajax clickable class" href="../classes/MM_Session.html">
|
||||||
|
<h1>MM_Session<a href="../classes/MM_Session.html">¶</a>
|
||||||
|
</h1>
|
||||||
|
<p class="short_description">Class to improve handling of PHP sessions</p>
|
||||||
|
<div class="details collapse"></div>
|
||||||
|
<a href="../classes/MM_Session.html" class="more">« More »</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row"><footer class="span12">
|
||||||
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -137,7 +137,7 @@
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -63,6 +63,9 @@
|
|||||||
<a href="../packages/miniMVC.App.html" title="App"><i class="icon-folder-open"></i>App</a><ul class="nav nav-list nav-packages"></ul>
|
<a href="../packages/miniMVC.App.html" title="App"><i class="icon-folder-open"></i>App</a><ul class="nav nav-list nav-packages"></ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
<a href="../packages/miniMVC.Libraries.html" title="Libraries"><i class="icon-folder-open"></i>Libraries</a><ul class="nav nav-list nav-packages"></ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
<a href="../packages/miniMVC.System.html" title="System"><i class="icon-folder-open"></i>System</a><ul class="nav nav-list nav-packages"></ul>
|
<a href="../packages/miniMVC.System.html" title="System"><i class="icon-folder-open"></i>System</a><ul class="nav nav-list nav-packages"></ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -413,6 +416,24 @@ display them cleanly</h2>
|
|||||||
<a href="../index.html"><i class="icon-folder-open"></i></a><span class="divider">\</span>
|
<a href="../index.html"><i class="icon-folder-open"></i></a><span class="divider">\</span>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="../packages/miniMVC.html">miniMVC</a></li>
|
<li><a href="../packages/miniMVC.html">miniMVC</a></li>
|
||||||
|
<span class="divider">\</span><li class="active"><a href="../packages/miniMVC.Libraries.html">Libraries</a></li>
|
||||||
|
</ul>
|
||||||
|
<div class="package-indent">
|
||||||
|
<h3>
|
||||||
|
<i class="icon-custom icon-class"></i> Classes and interfaces</h3>
|
||||||
|
<a name="MM_Session" id="MM_Session"></a><div class="element ajax clickable class" href="../classes/MM_Session.html">
|
||||||
|
<h1>MM_Session<a href="../classes/MM_Session.html">¶</a>
|
||||||
|
</h1>
|
||||||
|
<p class="short_description">Class to improve handling of PHP sessions</p>
|
||||||
|
<div class="details collapse"></div>
|
||||||
|
<a href="../classes/MM_Session.html" class="more">« More »</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
<li>
|
||||||
|
<a href="../index.html"><i class="icon-folder-open"></i></a><span class="divider">\</span>
|
||||||
|
</li>
|
||||||
|
<li><a href="../packages/miniMVC.html">miniMVC</a></li>
|
||||||
<span class="divider">\</span><li class="active"><a href="../packages/miniMVC.System.html">System</a></li>
|
<span class="divider">\</span><li class="active"><a href="../packages/miniMVC.System.html">System</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="package-indent">
|
<div class="package-indent">
|
||||||
@ -474,7 +495,7 @@ display them cleanly</h2>
|
|||||||
<div class="row"><footer class="span12">
|
<div class="row"><footer class="span12">
|
||||||
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
Template is built using <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap 2</a> and icons provided by <a href="http://glyphicons.com/">Glyphicons</a>.<br>
|
||||||
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor 2.0.0a2</a> and<br>
|
||||||
generated on 2012-05-03T11:38:41-04:00.<br></footer></div>
|
generated on 2012-05-03T13:23:53-04:00.<br></footer></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -95,7 +95,7 @@ and organizes database connections</p>]]></long-description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/classes/settings.php" hash="69d30a582c8ec7f2a29151aab896ce1e" package="Query">
|
<file path="sys/db/classes/settings.php" hash="25ad9e3275da6ce2f7330da60951bc89" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -510,7 +510,7 @@ directly - the settings should be safe!]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/classes/db_pdo.php" hash="343830257e8bc84fe3ef14bafbec5287" package="Query">
|
<file path="sys/db/classes/db_pdo.php" hash="4a064284a9d84b52efed79aea6180eeb" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -2494,7 +2494,7 @@ in place of the get() method]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/autoload.php" hash="170d8d1f4b74767beb653875962976ae" package="Query">
|
<file path="sys/db/autoload.php" hash="bdce746964645c481b110b7742a1691b" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -2568,7 +2568,7 @@ with array_map and glob]]></description>
|
|||||||
</argument>
|
</argument>
|
||||||
</function>
|
</function>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/drivers/pgsql/pgsql_sql.php" hash="28f1fe85be6eba57e8ec7373f885faec" package="Default">
|
<file path="sys/db/drivers/pgsql/pgsql_sql.php" hash="bacf01d4b1126f518af6577005ee7ef3" package="Default">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -2742,7 +2742,7 @@ with array_map and glob]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/drivers/pgsql/pgsql_util.php" hash="5bc6c47b681f4bdbb9385d8101666760" package="Query">
|
<file path="sys/db/drivers/pgsql/pgsql_util.php" hash="a649c231c8c931df95afecfe9df3dba4" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -3369,7 +3369,7 @@ with array_map and glob]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/drivers/mysql/mysql_util.php" hash="e6dbdd9b0b965f7e09ee0638ed4a7a35" package="Query">
|
<file path="sys/db/drivers/mysql/mysql_util.php" hash="ab0732f6bec207873af7a07ff1a0e1e8" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -3763,7 +3763,7 @@ with array_map and glob]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/drivers/sqlite/sqlite_util.php" hash="18cd637365896dd9cf94066e517cdaa8" package="Query">
|
<file path="sys/db/drivers/sqlite/sqlite_util.php" hash="5d6c375946512b2b5a5b39bd4ce55ac9" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -4762,7 +4762,7 @@ the query]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/drivers/firebird/firebird_driver.php" hash="4f7e9df014cc1df6b92f09f815b9837d" package="Query">
|
<file path="sys/db/drivers/firebird/firebird_driver.php" hash="6210fab7af8f0e2b5b95e048d2f80beb" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -5078,7 +5078,7 @@ the last query executed]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/db/drivers/firebird/firebird_util.php" hash="e51cf49b7bb1e2bb39ed5eab9bf6e98c" package="Query">
|
<file path="sys/db/drivers/firebird/firebird_util.php" hash="6c6a6d2b3f952ce5bf66c31ade5d346c" package="Query">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[Query]]></description>
|
<description><![CDATA[Query]]></description>
|
||||||
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
<long-description><![CDATA[<p>Free Query Builder / Database Abstraction Layer</p>]]></long-description>
|
||||||
@ -5219,7 +5219,7 @@ the last query executed]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/model.php" hash="01891d05727784017f7df2ba5c599ba3" package="miniMVC">
|
<file path="sys/core/model.php" hash="01891d05727784017f7df2ba5c599ba3" package="miniMVC">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -5271,275 +5271,7 @@ the last query executed]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/common.php" hash="60f0a7d073a110e7b52eaf325800a131" package="miniMVC">
|
<file path="sys/core/db.php" hash="2dd4b1ad5928f6f27318c77b6f4a130e" package="miniMVC">
|
||||||
<docblock line="2">
|
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
|
||||||
<tag line="2" name="package" description="miniMVC"/>
|
|
||||||
<tag line="2" name="author" description="Timothy J. Warren"/>
|
|
||||||
<tag line="2" name="copyright" description="Copyright (c) 2011 - 2012"/>
|
|
||||||
<tag line="2" name="link" description="https://github.com/timw4mail/miniMVC" link="https://github.com/timw4mail/miniMVC"/>
|
|
||||||
<tag line="2" name="license" description="http://philsturgeon.co.uk/code/dbad-license"/>
|
|
||||||
</docblock>
|
|
||||||
<include line="396" type="Require Once" package="Default">
|
|
||||||
<name>db/autoload.php</name>
|
|
||||||
</include>
|
|
||||||
<include line="399" type="Require Once" package="Default">
|
|
||||||
<name>miniMVC.php</name>
|
|
||||||
</include>
|
|
||||||
<function namespace="default" line="32" package="miniMVC">
|
|
||||||
<name>shutdown</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="25">
|
|
||||||
<description><![CDATA[Function to run on script shutdown
|
|
||||||
-used to catch most fatal errors, and
|
|
||||||
display them cleanly]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="25" name="return" description="" type="void">
|
|
||||||
<type by_reference="false">void</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="64" package="miniMVC">
|
|
||||||
<name>load_file</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="57">
|
|
||||||
<description><![CDATA[Function to search through the tree to find the necessary file]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="57" name="param" description="" type="string" variable="$file">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="57" name="param" description="" type="string" variable="$curr_path">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="57" name="return" description="" type="void">
|
|
||||||
<type by_reference="false">void</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="64">
|
|
||||||
<name>$file</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
<argument line="64">
|
|
||||||
<name>$curr_path</name>
|
|
||||||
<default><![CDATA[""]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="99" package="miniMVC">
|
|
||||||
<name>on_error</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="90">
|
|
||||||
<description><![CDATA[Custom error handler]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="90" name="param" description="" type="int" variable="$severity">
|
|
||||||
<type by_reference="false">int</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="90" name="param" description="" type="string" variable="$message">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="90" name="param" description="" type="string" variable="$filepath">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="90" name="param" description="" type="int" variable="$line">
|
|
||||||
<type by_reference="false">int</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="90" name="return" description="" type="\ErrorException">
|
|
||||||
<type by_reference="false">\ErrorException</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="99">
|
|
||||||
<name>$severity</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
<argument line="99">
|
|
||||||
<name>$message</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
<argument line="99">
|
|
||||||
<name>$filepath</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
<argument line="99">
|
|
||||||
<name>$line</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="112" package="miniMVC">
|
|
||||||
<name>on_exception</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="106">
|
|
||||||
<description><![CDATA[Custom exception handlererror_get_last]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="106" name="param" description="" type="\Exception" variable="$exception">
|
|
||||||
<type by_reference="false">\Exception</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="106" name="return" description="" type="void">
|
|
||||||
<type by_reference="false">void</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="112">
|
|
||||||
<name>$exception</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="134" package="miniMVC">
|
|
||||||
<name>is_like_array</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="128">
|
|
||||||
<description><![CDATA[Utility function to check if a variable is set, and is an array or object]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="128" name="param" description="" type="mixed" variable="$var">
|
|
||||||
<type by_reference="false">mixed</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="128" name="return" description="" type="bool">
|
|
||||||
<type by_reference="false">bool</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="134">
|
|
||||||
<name>$var</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="151" package="miniMVC">
|
|
||||||
<name>show_404</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="146">
|
|
||||||
<description><![CDATA[General 404 function]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="146" name="return" description="" type="void">
|
|
||||||
<type by_reference="false">void</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="175" package="miniMVC">
|
|
||||||
<name>show_error</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="169">
|
|
||||||
<description><![CDATA[Fatal Error page function]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="169" name="param" description="" type="string" variable="$message">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="169" name="param" description="" type="int" variable="$status_code">
|
|
||||||
<type by_reference="false">int</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="175">
|
|
||||||
<name>$message</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
<argument line="175">
|
|
||||||
<name>$status_code</name>
|
|
||||||
<default><![CDATA[null]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="200" package="miniMVC">
|
|
||||||
<name>controller_methods</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="194">
|
|
||||||
<description><![CDATA[Returns routable methods for the specified controller class]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="194" name="param" description="" type="string" variable="$controller">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="194" name="return" description="" type="array">
|
|
||||||
<type by_reference="false">array</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="200">
|
|
||||||
<name>$controller</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="218" package="miniMVC">
|
|
||||||
<name>route</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="213">
|
|
||||||
<description><![CDATA[Calls the appropriate module/controller/function based on the url]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="213" name="return" description="" type="void">
|
|
||||||
<type by_reference="false">void</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="342" package="miniMVC">
|
|
||||||
<name>site_url</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="336">
|
|
||||||
<description><![CDATA[Returns a full url from a url segment]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="336" name="param" description="" type="string" variable="$segment">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="336" name="return" description="" type="string">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="342">
|
|
||||||
<name>$segment</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="356" package="miniMVC">
|
|
||||||
<name>to_string</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="349">
|
|
||||||
<description><![CDATA[Prints out the contents of the object]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="349" name="param" description="" type="\object/array" variable="$data">
|
|
||||||
<type by_reference="false">\object/array</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="349" name="param" description="" type="string" variable="$method">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="349" name="return" description="" type="string">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="356">
|
|
||||||
<name>$data</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
<argument line="356">
|
|
||||||
<name>$method</name>
|
|
||||||
<default><![CDATA['print_r']]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
<function namespace="default" line="390" package="miniMVC">
|
|
||||||
<name>do_include</name>
|
|
||||||
<type>function</type>
|
|
||||||
<docblock line="384">
|
|
||||||
<description><![CDATA[Array_map callback to load a folder of classes at once]]></description>
|
|
||||||
<long-description><![CDATA[]]></long-description>
|
|
||||||
<tag line="384" name="param" description="" type="string" variable="$path">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="384" name="return" description="" type="void">
|
|
||||||
<type by_reference="false">void</type>
|
|
||||||
</tag>
|
|
||||||
</docblock>
|
|
||||||
<argument line="390">
|
|
||||||
<name>$path</name>
|
|
||||||
<default><![CDATA[]]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</function>
|
|
||||||
</file>
|
|
||||||
<file path="sys/db.php" hash="fb3bc02ed59a592ed41e961727a63c2a" package="miniMVC">
|
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -5653,7 +5385,7 @@ display them cleanly]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/miniMVC.php" hash="beab708bbf1a7169e150bd1948d26ce7" package="miniMVC">
|
<file path="sys/core/miniMVC.php" hash="c2a34e78f2511d0be859165251595469" package="miniMVC">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -5869,7 +5601,7 @@ dynamic methods]]></description>
|
|||||||
<type/>
|
<type/>
|
||||||
</argument>
|
</argument>
|
||||||
</method>
|
</method>
|
||||||
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="314" package="">
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="313" package="">
|
||||||
<name>load_class</name>
|
<name>load_class</name>
|
||||||
<type>function</type>
|
<type>function</type>
|
||||||
<docblock line="307">
|
<docblock line="307">
|
||||||
@ -5878,51 +5610,43 @@ dynamic methods]]></description>
|
|||||||
<tag line="307" name="param" description="" type="string" variable="$name">
|
<tag line="307" name="param" description="" type="string" variable="$name">
|
||||||
<type by_reference="false">string</type>
|
<type by_reference="false">string</type>
|
||||||
</tag>
|
</tag>
|
||||||
<tag line="307" name="param" description="" type="string" variable="$type">
|
|
||||||
<type by_reference="false">string</type>
|
|
||||||
</tag>
|
|
||||||
<tag line="307" name="return" description="" type="void">
|
<tag line="307" name="return" description="" type="void">
|
||||||
<type by_reference="false">void</type>
|
<type by_reference="false">void</type>
|
||||||
</tag>
|
</tag>
|
||||||
</docblock>
|
</docblock>
|
||||||
<argument line="314">
|
<argument line="313">
|
||||||
<name>$name</name>
|
<name>$name</name>
|
||||||
<default><![CDATA[]]></default>
|
<default><![CDATA[]]></default>
|
||||||
<type/>
|
<type/>
|
||||||
</argument>
|
</argument>
|
||||||
<argument line="314">
|
|
||||||
<name>$type</name>
|
|
||||||
<default><![CDATA['class']]></default>
|
|
||||||
<type/>
|
|
||||||
</argument>
|
|
||||||
</method>
|
</method>
|
||||||
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="370" package="">
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="371" package="">
|
||||||
<name>unload</name>
|
<name>unload</name>
|
||||||
<type>function</type>
|
<type>function</type>
|
||||||
<docblock line="365">
|
<docblock line="366">
|
||||||
<description><![CDATA[Convenience function to remove an object from the singleton]]></description>
|
<description><![CDATA[Convenience function to remove an object from the singleton]]></description>
|
||||||
<long-description><![CDATA[]]></long-description>
|
<long-description><![CDATA[]]></long-description>
|
||||||
<tag line="365" name="param" description="" type="string" variable="$name">
|
<tag line="366" name="param" description="" type="string" variable="$name">
|
||||||
<type by_reference="false">string</type>
|
<type by_reference="false">string</type>
|
||||||
</tag>
|
</tag>
|
||||||
</docblock>
|
</docblock>
|
||||||
<argument line="370">
|
<argument line="371">
|
||||||
<name>$name</name>
|
<name>$name</name>
|
||||||
<default><![CDATA[]]></default>
|
<default><![CDATA[]]></default>
|
||||||
<type/>
|
<type/>
|
||||||
</argument>
|
</argument>
|
||||||
</method>
|
</method>
|
||||||
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="385" package="">
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="386" package="">
|
||||||
<name>load_config</name>
|
<name>load_config</name>
|
||||||
<type>function</type>
|
<type>function</type>
|
||||||
<docblock line="380">
|
<docblock line="381">
|
||||||
<description><![CDATA[Convenience function to load config files]]></description>
|
<description><![CDATA[Convenience function to load config files]]></description>
|
||||||
<long-description><![CDATA[]]></long-description>
|
<long-description><![CDATA[]]></long-description>
|
||||||
<tag line="380" name="param" description="" type="string" variable="$name">
|
<tag line="381" name="param" description="" type="string" variable="$name">
|
||||||
<type by_reference="false">string</type>
|
<type by_reference="false">string</type>
|
||||||
</tag>
|
</tag>
|
||||||
</docblock>
|
</docblock>
|
||||||
<argument line="385">
|
<argument line="386">
|
||||||
<name>$name</name>
|
<name>$name</name>
|
||||||
<default><![CDATA[]]></default>
|
<default><![CDATA[]]></default>
|
||||||
<type/>
|
<type/>
|
||||||
@ -5930,7 +5654,7 @@ dynamic methods]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/page.php" hash="ad9390e0d82e607ba67a4705a2ab8624" package="miniMVC">
|
<file path="sys/core/page.php" hash="fe5e54476f922c47baf2ab9040a55f5b" package="miniMVC">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -6497,7 +6221,7 @@ page.</p>]]></long-description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/controller.php" hash="765cd2295836720906bdc3a4e3453626" package="miniMVC">
|
<file path="sys/core/controller.php" hash="eac8dd511fb6b91e187a4749fd619b17" package="miniMVC">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -6603,7 +6327,7 @@ page.</p>]]></long-description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="sys/output.php" hash="bbcd277d43771103de6f189f99c2a061" package="Default">
|
<file path="sys/core/output.php" hash="b95af3c4fb386e999b088366cce23044" package="Default">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -6733,7 +6457,362 @@ Used for outputing HTML]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="index.php" hash="c31554a930dad7ae4ffda69df87ed227" package="miniMVC">
|
<file path="sys/libraries/session.php" hash="08c3faccd0c710c5cf5acc1d3fc3ba23" package="miniMVC">
|
||||||
|
<docblock line="2">
|
||||||
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
|
<tag line="2" name="package" description="miniMVC"/>
|
||||||
|
<tag line="2" name="author" description="Timothy J. Warren"/>
|
||||||
|
<tag line="2" name="copyright" description="Copyright (c) 2011 - 2012"/>
|
||||||
|
<tag line="2" name="link" description="https://github.com/timw4mail/miniMVC" link="https://github.com/timw4mail/miniMVC"/>
|
||||||
|
<tag line="2" name="license" description="http://philsturgeon.co.uk/code/dbad-license"/>
|
||||||
|
</docblock>
|
||||||
|
<class final="false" abstract="false" namespace="default" line="22" package="miniMVC\Libraries">
|
||||||
|
<name>MM_Session</name>
|
||||||
|
<full_name>\MM_Session</full_name>
|
||||||
|
<extends/>
|
||||||
|
<docblock line="16">
|
||||||
|
<description><![CDATA[Class to improve handling of PHP sessions]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="16" name="package" description="miniMVC"/>
|
||||||
|
<tag line="16" name="subpackage" description="Libraries"/>
|
||||||
|
</docblock>
|
||||||
|
<method final="false" abstract="false" static="false" visibility="protected" namespace="default" line="32" package="">
|
||||||
|
<name>__construct</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="29">
|
||||||
|
<description><![CDATA[Start a session]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
</docblock>
|
||||||
|
</method>
|
||||||
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="53" package="">
|
||||||
|
<name>__set</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="46">
|
||||||
|
<description><![CDATA[Set a session value]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="46" name="param" description="" type="string" variable="$key">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="46" name="param" description="" type="mixed" variable="$val">
|
||||||
|
<type by_reference="false">mixed</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="46" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="53">
|
||||||
|
<name>$key</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="53">
|
||||||
|
<name>$val</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</method>
|
||||||
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="66" package="">
|
||||||
|
<name>__get</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="60">
|
||||||
|
<description><![CDATA[Retreive a session value]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="60" name="param" description="" type="string" variable="$key">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="60" name="return" description="" type="mixed">
|
||||||
|
<type by_reference="false">mixed</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="66">
|
||||||
|
<name>$key</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</method>
|
||||||
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="78" package="">
|
||||||
|
<name>destroy</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="73">
|
||||||
|
<description><![CDATA[Destroy a session]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="73" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
|
</file>
|
||||||
|
<file path="sys/common.php" hash="c4342203d1f8cc49ff444580ee71dfdf" package="miniMVC">
|
||||||
|
<docblock line="2">
|
||||||
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
|
<tag line="2" name="package" description="miniMVC"/>
|
||||||
|
<tag line="2" name="author" description="Timothy J. Warren"/>
|
||||||
|
<tag line="2" name="copyright" description="Copyright (c) 2011 - 2012"/>
|
||||||
|
<tag line="2" name="link" description="https://github.com/timw4mail/miniMVC" link="https://github.com/timw4mail/miniMVC"/>
|
||||||
|
<tag line="2" name="license" description="http://philsturgeon.co.uk/code/dbad-license"/>
|
||||||
|
</docblock>
|
||||||
|
<include line="396" type="Require Once" package="Default">
|
||||||
|
<name>db/autoload.php</name>
|
||||||
|
</include>
|
||||||
|
<include line="399" type="Require Once" package="Default">
|
||||||
|
<name>core/miniMVC.php</name>
|
||||||
|
</include>
|
||||||
|
<function namespace="default" line="32" package="miniMVC">
|
||||||
|
<name>shutdown</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="25">
|
||||||
|
<description><![CDATA[Function to run on script shutdown
|
||||||
|
-used to catch most fatal errors, and
|
||||||
|
display them cleanly]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="25" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="64" package="miniMVC">
|
||||||
|
<name>load_file</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="57">
|
||||||
|
<description><![CDATA[Function to search through the tree to find the necessary file]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="57" name="param" description="" type="string" variable="$file">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="57" name="param" description="" type="string" variable="$curr_path">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="57" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="64">
|
||||||
|
<name>$file</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="64">
|
||||||
|
<name>$curr_path</name>
|
||||||
|
<default><![CDATA[""]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="99" package="miniMVC">
|
||||||
|
<name>on_error</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="90">
|
||||||
|
<description><![CDATA[Custom error handler]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="90" name="param" description="" type="int" variable="$severity">
|
||||||
|
<type by_reference="false">int</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="90" name="param" description="" type="string" variable="$message">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="90" name="param" description="" type="string" variable="$filepath">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="90" name="param" description="" type="int" variable="$line">
|
||||||
|
<type by_reference="false">int</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="90" name="return" description="" type="\ErrorException">
|
||||||
|
<type by_reference="false">\ErrorException</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="99">
|
||||||
|
<name>$severity</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="99">
|
||||||
|
<name>$message</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="99">
|
||||||
|
<name>$filepath</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="99">
|
||||||
|
<name>$line</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="112" package="miniMVC">
|
||||||
|
<name>on_exception</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="106">
|
||||||
|
<description><![CDATA[Custom exception handlererror_get_last]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="106" name="param" description="" type="\Exception" variable="$exception">
|
||||||
|
<type by_reference="false">\Exception</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="106" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="112">
|
||||||
|
<name>$exception</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="134" package="miniMVC">
|
||||||
|
<name>is_like_array</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="128">
|
||||||
|
<description><![CDATA[Utility function to check if a variable is set, and is an array or object]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="128" name="param" description="" type="mixed" variable="$var">
|
||||||
|
<type by_reference="false">mixed</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="128" name="return" description="" type="bool">
|
||||||
|
<type by_reference="false">bool</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="134">
|
||||||
|
<name>$var</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="151" package="miniMVC">
|
||||||
|
<name>show_404</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="146">
|
||||||
|
<description><![CDATA[General 404 function]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="146" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="175" package="miniMVC">
|
||||||
|
<name>show_error</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="169">
|
||||||
|
<description><![CDATA[Fatal Error page function]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="169" name="param" description="" type="string" variable="$message">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="169" name="param" description="" type="int" variable="$status_code">
|
||||||
|
<type by_reference="false">int</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="175">
|
||||||
|
<name>$message</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="175">
|
||||||
|
<name>$status_code</name>
|
||||||
|
<default><![CDATA[null]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="200" package="miniMVC">
|
||||||
|
<name>controller_methods</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="194">
|
||||||
|
<description><![CDATA[Returns routable methods for the specified controller class]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="194" name="param" description="" type="string" variable="$controller">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="194" name="return" description="" type="array">
|
||||||
|
<type by_reference="false">array</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="200">
|
||||||
|
<name>$controller</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="218" package="miniMVC">
|
||||||
|
<name>route</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="213">
|
||||||
|
<description><![CDATA[Calls the appropriate module/controller/function based on the url]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="213" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="342" package="miniMVC">
|
||||||
|
<name>site_url</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="336">
|
||||||
|
<description><![CDATA[Returns a full url from a url segment]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="336" name="param" description="" type="string" variable="$segment">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="336" name="return" description="" type="string">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="342">
|
||||||
|
<name>$segment</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="356" package="miniMVC">
|
||||||
|
<name>to_string</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="349">
|
||||||
|
<description><![CDATA[Prints out the contents of the object]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="349" name="param" description="" type="\object/array" variable="$data">
|
||||||
|
<type by_reference="false">\object/array</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="349" name="param" description="" type="string" variable="$method">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="349" name="return" description="" type="string">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="356">
|
||||||
|
<name>$data</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
<argument line="356">
|
||||||
|
<name>$method</name>
|
||||||
|
<default><![CDATA['print_r']]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
<function namespace="default" line="390" package="miniMVC">
|
||||||
|
<name>do_include</name>
|
||||||
|
<type>function</type>
|
||||||
|
<docblock line="384">
|
||||||
|
<description><![CDATA[Array_map callback to load a folder of classes at once]]></description>
|
||||||
|
<long-description><![CDATA[]]></long-description>
|
||||||
|
<tag line="384" name="param" description="" type="string" variable="$path">
|
||||||
|
<type by_reference="false">string</type>
|
||||||
|
</tag>
|
||||||
|
<tag line="384" name="return" description="" type="void">
|
||||||
|
<type by_reference="false">void</type>
|
||||||
|
</tag>
|
||||||
|
</docblock>
|
||||||
|
<argument line="390">
|
||||||
|
<name>$path</name>
|
||||||
|
<default><![CDATA[]]></default>
|
||||||
|
<type/>
|
||||||
|
</argument>
|
||||||
|
</function>
|
||||||
|
</file>
|
||||||
|
<file path="index.php" hash="a6fec7a10150d40748e88987715e6510" package="miniMVC">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -6888,7 +6967,7 @@ Used for outputing HTML]]></description>
|
|||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
</file>
|
</file>
|
||||||
<file path="modules/welcome/controllers/welcome.php" hash="7c35135fe3c1510d57e332e337d640e6" package="miniMVC">
|
<file path="modules/welcome/controllers/welcome.php" hash="b46fff4b3fd55129850e8edff54a75f5" package="miniMVC">
|
||||||
<docblock line="2">
|
<docblock line="2">
|
||||||
<description><![CDATA[MiniMVC]]></description>
|
<description><![CDATA[MiniMVC]]></description>
|
||||||
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
<long-description><![CDATA[<p>Convention-based micro-framework for PHP</p>]]></long-description>
|
||||||
@ -6930,13 +7009,13 @@ Used for outputing HTML]]></description>
|
|||||||
</tag>
|
</tag>
|
||||||
</docblock>
|
</docblock>
|
||||||
</method>
|
</method>
|
||||||
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="50" package="">
|
<method final="false" abstract="false" static="false" visibility="public" namespace="default" line="51" package="">
|
||||||
<name>php</name>
|
<name>php</name>
|
||||||
<type>function</type>
|
<type>function</type>
|
||||||
<docblock line="45">
|
<docblock line="46">
|
||||||
<description><![CDATA[welcome/php route]]></description>
|
<description><![CDATA[welcome/php route]]></description>
|
||||||
<long-description><![CDATA[]]></long-description>
|
<long-description><![CDATA[]]></long-description>
|
||||||
<tag line="45" name="return" description="" type="void">
|
<tag line="46" name="return" description="" type="void">
|
||||||
<type by_reference="false">void</type>
|
<type by_reference="false">void</type>
|
||||||
</tag>
|
</tag>
|
||||||
</docblock>
|
</docblock>
|
||||||
@ -6952,6 +7031,7 @@ Used for outputing HTML]]></description>
|
|||||||
</package>
|
</package>
|
||||||
<package name="miniMVC" full_name="miniMVC">
|
<package name="miniMVC" full_name="miniMVC">
|
||||||
<package name="App" full_name="miniMVC\App"/>
|
<package name="App" full_name="miniMVC\App"/>
|
||||||
|
<package name="Libraries" full_name="miniMVC\Libraries"/>
|
||||||
<package name="System" full_name="miniMVC\System"/>
|
<package name="System" full_name="miniMVC\System"/>
|
||||||
</package>
|
</package>
|
||||||
<namespace name="default" full_name="default"/>
|
<namespace name="default" full_name="default"/>
|
||||||
|
@ -38,8 +38,9 @@ class Welcome extends MM_Controller {
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$output = $this->page->set_message('info', "This is just a test message", TRUE);
|
$this->page->build_header();
|
||||||
$this->page->output_string($output);
|
$output = $this->page->set_message('info', "This is just a test message");
|
||||||
|
$this->page->build_footer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 31ba0881ea6088c6b141d6b75d6f2f302e61585c
|
|
@ -396,7 +396,7 @@ function do_include($path)
|
|||||||
require_once(MM_SYS_PATH.'db/autoload.php');
|
require_once(MM_SYS_PATH.'db/autoload.php');
|
||||||
|
|
||||||
// Load system libraries
|
// Load system libraries
|
||||||
require_once(MM_SYS_PATH.'miniMVC.php');
|
require_once(MM_SYS_PATH.'core/miniMVC.php');
|
||||||
array_map('do_include', glob(MM_SYS_PATH.'*.php'));
|
array_map('do_include', glob(MM_SYS_PATH.'core/*.php'));
|
||||||
|
|
||||||
// End of common.php
|
// End of common.php
|
@ -308,22 +308,10 @@ class miniMVC extends MM {
|
|||||||
* Method to load classes into the singleton
|
* Method to load classes into the singleton
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $type
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function load_class($name, $type='class')
|
public function load_class($name)
|
||||||
{
|
{
|
||||||
switch($type)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
$path = MM_APP_PATH . "classes/{$name}.php";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "sys":
|
|
||||||
$path = MM_SYS_PATH . "{$name}.php";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In a subdirectory? No problem
|
// In a subdirectory? No problem
|
||||||
if (strpos("/", $name) !== FALSE)
|
if (strpos("/", $name) !== FALSE)
|
||||||
{
|
{
|
||||||
@ -331,6 +319,16 @@ class miniMVC extends MM {
|
|||||||
$name = $n[count($n) -1];
|
$name = $n[count($n) -1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try system library first, then app library
|
||||||
|
$path = MM_SYS_PATH . "libraries/{$name}.php";
|
||||||
|
$name = 'MM_'.$name;
|
||||||
|
|
||||||
|
if ( ! is_file($path))
|
||||||
|
{
|
||||||
|
$path = MM_APP_PATH . "classes/{$name}.php";
|
||||||
|
$name = str_replace('MM_', '', $name);
|
||||||
|
}
|
||||||
|
|
||||||
$class = "{$name}";
|
$class = "{$name}";
|
||||||
|
|
||||||
// Load the class file if need be
|
// Load the class file if need be
|
||||||
@ -345,10 +343,13 @@ class miniMVC extends MM {
|
|||||||
// Create the object, and add it to the current miniMVC object
|
// Create the object, and add it to the current miniMVC object
|
||||||
if (class_exists($class, FALSE))
|
if (class_exists($class, FALSE))
|
||||||
{
|
{
|
||||||
|
// Remove MM_ prefix from name
|
||||||
|
$name = str_replace('MM_', '', $name);
|
||||||
|
|
||||||
if ( ! isset($this->$name))
|
if ( ! isset($this->$name))
|
||||||
{
|
{
|
||||||
// Call a singleton, if the get_instance method exists
|
// Call a singleton, if the get_instance method exists
|
||||||
if (is_callable(array($class, 'get_instance')))
|
if (method_exists($class, 'get_instance'))
|
||||||
{
|
{
|
||||||
$this->$name =& $class::get_instance();
|
$this->$name =& $class::get_instance();
|
||||||
return;
|
return;
|
@ -1,83 +0,0 @@
|
|||||||
# Query
|
|
||||||
|
|
||||||
A query builder/abstraction layer, using prepared queries for security.
|
|
||||||
|
|
||||||
[![Build Status](https://secure.travis-ci.org/timw4mail/Query.png)](http://travis-ci.org/timw4mail/Query)
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
* Pdo extensions for the databases you wish to use (unless it's Firebird, in which case, the interbase extension is required)
|
|
||||||
* PHP 5.2+
|
|
||||||
|
|
||||||
## Databases Supported
|
|
||||||
|
|
||||||
* Firebird
|
|
||||||
* MySQL
|
|
||||||
* PostgreSQL
|
|
||||||
* SQLite
|
|
||||||
* Others, via ODBC
|
|
||||||
|
|
||||||
## Including Query in your application
|
|
||||||
|
|
||||||
To include Query in your PHP project, just include the `autoload.php` file. This will automatically load the classes that are supported by the current PHP installation.
|
|
||||||
|
|
||||||
|
|
||||||
## Connecting
|
|
||||||
|
|
||||||
Create a connection array or object similar to this:
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$params = array(
|
|
||||||
'type' => 'mysql',
|
|
||||||
'host' => 'localhost',
|
|
||||||
'user' => 'root',
|
|
||||||
'pass' => '',
|
|
||||||
'port' => '3306',
|
|
||||||
'database' => 'test_db',
|
|
||||||
|
|
||||||
// Only required
|
|
||||||
// SQLite or Firebird
|
|
||||||
'file' => '/path/to/db/file',
|
|
||||||
);
|
|
||||||
|
|
||||||
$db = new Query_Builder($params);
|
|
||||||
|
|
||||||
The parameters required depend on the database.
|
|
||||||
|
|
||||||
### Running Queries
|
|
||||||
Query uses the same interface as CodeIgniter's [Active Record class](http://codeigniter.com/user_guide/database/active_record.html). However, it does not implement the `insert_batch` or `update_batch` methods.
|
|
||||||
|
|
||||||
####You can also run queries manually.
|
|
||||||
|
|
||||||
To run a prepared statement, call
|
|
||||||
`$db->prepare_execute($sql, $params)`.
|
|
||||||
|
|
||||||
To run a plain query, `$db->query($sql)`
|
|
||||||
|
|
||||||
### Retrieving Results:
|
|
||||||
|
|
||||||
An example of a moderately complex query:
|
|
||||||
|
|
||||||
$query = $db->select('id, key as k, val')
|
|
||||||
->from('table t')
|
|
||||||
->where('k >', 3)
|
|
||||||
->or_where('id !=' 5)
|
|
||||||
->order_by('val', 'DESC')
|
|
||||||
->limit(3, 1)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
This will generate a query similar to (with this being the output for a Postgres database):
|
|
||||||
|
|
||||||
SELECT "id", "key" AS "k", "val"
|
|
||||||
FROM "table" "t"
|
|
||||||
WHERE "k" > ?
|
|
||||||
OR "id" != ?
|
|
||||||
ORDER BY "val" DESC
|
|
||||||
LIMIT 3 OFFSET 1
|
|
||||||
|
|
||||||
|
|
||||||
To retreive the results of a query, use the PDO method [fetch](http://php.net/manual/en/pdostatement.fetch.php) and/or [fetchAll](http://php.net/manual/en/pdostatement.fetchall.php).
|
|
||||||
|
|
||||||
$query = $db->get('table_name');
|
|
||||||
|
|
||||||
$results = $query->fetchAll(PDO::FETCH_ASSOC);
|
|
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<phpdoc>
|
|
||||||
<title>Query</title>
|
|
||||||
<parser>
|
|
||||||
<target>docs</target>
|
|
||||||
</parser>
|
|
||||||
<transformer>
|
|
||||||
<target>docs</target>
|
|
||||||
</transformer>
|
|
||||||
<transformations>
|
|
||||||
<template name="responsive" />
|
|
||||||
</transformations>
|
|
||||||
<files>
|
|
||||||
<directory>.</directory>
|
|
||||||
<directory>tests</directory>
|
|
||||||
<ignore>tests/*</ignore>
|
|
||||||
</files>
|
|
||||||
</phpdoc>
|
|
@ -1,73 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* OpenSQLManager
|
|
||||||
*
|
|
||||||
* Free Database manager for Open Source Databases
|
|
||||||
*
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/OpenSQLManager
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* CoreTest class - Compatibility and core functionality tests
|
|
||||||
*
|
|
||||||
* @extends UnitTestCase
|
|
||||||
*/
|
|
||||||
class CoreTest extends UnitTestCase {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __construct function.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TestPHPVersion function.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function TestPHPVersion()
|
|
||||||
{
|
|
||||||
$this->assertTrue(version_compare(PHP_VERSION, "5.2", "ge"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TestHasPDO function.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function TestHasPDO()
|
|
||||||
{
|
|
||||||
// PDO class exists
|
|
||||||
$this->assertTrue(class_exists('PDO'));
|
|
||||||
|
|
||||||
|
|
||||||
// Make sure at least one of the supported drivers is enabled
|
|
||||||
$supported = array(
|
|
||||||
'mysql',
|
|
||||||
'pgsql',
|
|
||||||
'odbc',
|
|
||||||
'sqlite',
|
|
||||||
);
|
|
||||||
|
|
||||||
$drivers = pdo_drivers();
|
|
||||||
|
|
||||||
$num_supported = count(array_intersect($drivers, $supported));
|
|
||||||
|
|
||||||
$this->assertTrue($num_supported > 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,430 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query builder parent test class
|
|
||||||
*/
|
|
||||||
abstract class QBTest extends UnitTestCase {
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! Get Tests
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGet()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->get('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetLimit()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->get('create_test', 2);
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetLimitSkip()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->get('create_test', 2, 1);
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetWhere()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->get_where('create_test', array('id !=' => 1), 2, 1);
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestHaving()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id')
|
|
||||||
->from('create_test')
|
|
||||||
->group_by('id')
|
|
||||||
->having(array('id >' => 1))
|
|
||||||
->having('id !=', 3)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestOrHaving()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id')
|
|
||||||
->from('create_test')
|
|
||||||
->group_by('id')
|
|
||||||
->having(array('id >' => 1))
|
|
||||||
->or_having('id !=', 3)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetViews()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$this->assertTrue(is_array($this->db->get_views()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! Select Tests
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectWhereGet()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->where('id >', 1)
|
|
||||||
->where('id <', 900)
|
|
||||||
->get('create_test', 2, 1);
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectWhereGet2()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->where('id !=', 1)
|
|
||||||
->get('create_test', 2, 1);
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectMax()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select_max('id', 'di')
|
|
||||||
->get('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectMin()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select_min('id', 'di')
|
|
||||||
->get('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectAvg()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select_avg('id', 'di')
|
|
||||||
->get('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectSum()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select_sum('id', 'di')
|
|
||||||
->get('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectDistinct()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select_sum('id', 'di')
|
|
||||||
->distinct()
|
|
||||||
->get('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectGet()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->get('create_test', 2, 1);
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectFromGet()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test ct')
|
|
||||||
->where('id >', 1)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSelectFromLimitGet()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test ct')
|
|
||||||
->where('id >', 1)
|
|
||||||
->limit(3)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! Query modifier tests
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestOrderBy()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test')
|
|
||||||
->where('id >', 0)
|
|
||||||
->where('id <', 9000)
|
|
||||||
->order_by('id', 'DESC')
|
|
||||||
->order_by('k', 'ASC')
|
|
||||||
->limit(5,2)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestOrderByRandom()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test')
|
|
||||||
->where('id >', 0)
|
|
||||||
->where('id <', 9000)
|
|
||||||
->order_by('id', 'rand')
|
|
||||||
->limit(5,2)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGroupBy()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test')
|
|
||||||
->where('id >', 0)
|
|
||||||
->where('id <', 9000)
|
|
||||||
->group_by('k')
|
|
||||||
->group_by('id')
|
|
||||||
->group_by('val')
|
|
||||||
->order_by('id', 'DESC')
|
|
||||||
->order_by('k', 'ASC')
|
|
||||||
->limit(5,2)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestOrWhere()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test')
|
|
||||||
->where(' id ', 1)
|
|
||||||
->or_where('key >', 0)
|
|
||||||
->limit(2, 1)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestLike()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->from('create_test')
|
|
||||||
->like('key', 'og')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestJoin()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->from('create_test')
|
|
||||||
->join('create_join cj', 'cj.id = create_test.id')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! DB update tests
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestInsert()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->set('id', 4)
|
|
||||||
->set('key', 4)
|
|
||||||
->set('val', 5)
|
|
||||||
->insert('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestUpdate()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->set('id', 4)
|
|
||||||
->set('key', 'gogle')
|
|
||||||
->set('val', 'non-word')
|
|
||||||
->where('id', 4)
|
|
||||||
->update('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestDelete()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->where('id', 4)->delete('create_test');
|
|
||||||
|
|
||||||
$this->assertIsA($query, 'PDOStatement');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// ! Non-data read queries
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCountAll()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
$query = $this->db->count_all('create_test');
|
|
||||||
|
|
||||||
$this->assertTrue(is_numeric($query));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCountAllResults()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
$query = $this->db->count_all_results('create_test');
|
|
||||||
|
|
||||||
$this->assertTrue(is_numeric($query));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCountAllResults2()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$query = $this->db->select('id, key as k, val')
|
|
||||||
->from('create_test')
|
|
||||||
->where(' id ', 1)
|
|
||||||
->or_where('key >', 0)
|
|
||||||
->limit(2, 1)
|
|
||||||
->count_all_results();
|
|
||||||
|
|
||||||
$this->assertTrue(is_numeric($query));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestNumRows()
|
|
||||||
{
|
|
||||||
$query = $this->db->get('create_test');
|
|
||||||
|
|
||||||
$this->assertTrue(is_numeric($this->db->num_rows()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of db_qb_test.php
|
|
@ -1,68 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parent Database Test Class
|
|
||||||
*/
|
|
||||||
abstract class DBTest extends UnitTestCase {
|
|
||||||
|
|
||||||
abstract public function TestConnection();
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function tearDown()
|
|
||||||
{
|
|
||||||
$this->db = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetTables()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$tables = $this->db->get_tables();
|
|
||||||
$this->assertTrue(is_array($tables));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSystemTables()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$tables = $this->db->get_system_tables();
|
|
||||||
|
|
||||||
$this->assertTrue(is_array($tables));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCreateTransaction()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestBackupData()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_string($this->db->util->backup_data()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// End of db_test.php
|
|
@ -1,91 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* OpenSQLManager
|
|
||||||
*
|
|
||||||
* Free Database manager for Open Source Databases
|
|
||||||
*
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/OpenSQLManager
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Settings Class Test Class
|
|
||||||
*/
|
|
||||||
class SettingsTest extends UnitTestCase {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->settings =& Settings::get_instance();
|
|
||||||
|
|
||||||
// Make sure to delete 'foo' if it exists
|
|
||||||
$this->settings->remove_db('foo');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestExists()
|
|
||||||
{
|
|
||||||
$this->assertIsA($this->settings, 'Settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetEmptyDBs()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_object($this->settings->get_dbs()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetNull()
|
|
||||||
{
|
|
||||||
$this->assertFalse(isset($this->settings->foo));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSet()
|
|
||||||
{
|
|
||||||
$bar = $this->settings->foo = 'bar';
|
|
||||||
|
|
||||||
$this->assertEqual('bar', $bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGet()
|
|
||||||
{
|
|
||||||
$this->assertEqual('bar', $this->settings->foo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestSetDBProperty()
|
|
||||||
{
|
|
||||||
$res = $this->settings->__set('dbs', 2);
|
|
||||||
$this->assertFalse($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetEmptyDB()
|
|
||||||
{
|
|
||||||
$this->assertFalse($this->settings->get_db('foo'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestAddDB()
|
|
||||||
{
|
|
||||||
$this->settings->add_db('foo', array());
|
|
||||||
|
|
||||||
$db = $this->settings->get_db('foo');
|
|
||||||
|
|
||||||
$this->assertTrue(isset($db));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Firebird Query Builder Tests
|
|
||||||
*/
|
|
||||||
class FirebirdQBTest extends QBTest {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
|
|
||||||
|
|
||||||
// Test the query builder
|
|
||||||
$params = new Stdclass();
|
|
||||||
$params->type = 'firebird';
|
|
||||||
$params->file = $dbpath;
|
|
||||||
$params->host = 'localhost';
|
|
||||||
$params->user = 'sysdba';
|
|
||||||
$params->pass = 'masterkey';
|
|
||||||
$this->db = new Query_Builder($params);
|
|
||||||
|
|
||||||
// echo '<hr /> Firebird Queries <hr />';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,221 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FirebirdTest class.
|
|
||||||
*
|
|
||||||
* @extends UnitTestCase
|
|
||||||
*/
|
|
||||||
class FirebirdTest extends DBTest {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
$dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
|
|
||||||
|
|
||||||
// Test the db driver directly
|
|
||||||
$this->db = new Firebird('localhost:'.$dbpath);
|
|
||||||
$this->tables = $this->db->get_tables();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function tearDown()
|
|
||||||
{
|
|
||||||
unset($this->db);
|
|
||||||
unset($this->tables);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestConnection()
|
|
||||||
{
|
|
||||||
$this->assertIsA($this->db, 'Firebird');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetTables()
|
|
||||||
{
|
|
||||||
$tables = $this->tables;
|
|
||||||
$this->assertTrue(is_array($tables));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSystemTables()
|
|
||||||
{
|
|
||||||
$only_system = TRUE;
|
|
||||||
|
|
||||||
$tables = $this->db->get_system_tables();
|
|
||||||
|
|
||||||
foreach($tables as $t)
|
|
||||||
{
|
|
||||||
if(stripos($t, 'rdb$') !== 0 && stripos($t, 'mon$') !== 0)
|
|
||||||
{
|
|
||||||
$only_system = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertTrue($only_system);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCreateTransaction()
|
|
||||||
{
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*public function TestCreateTable()
|
|
||||||
{
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->sql->create_table('create_join', array(
|
|
||||||
'id' => 'SMALLINT',
|
|
||||||
'key' => 'VARCHAR(64)',
|
|
||||||
'val' => 'BLOB SUB_TYPE TEXT'
|
|
||||||
));
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//This test fails for an unknown reason, when clearly the table exists
|
|
||||||
//Reset
|
|
||||||
$this->tearDown();
|
|
||||||
$this->setUp();
|
|
||||||
|
|
||||||
//Check
|
|
||||||
$table_exists = (bool)in_array('create_test', $this->tables);
|
|
||||||
|
|
||||||
echo "create_test exists :".(int)$table_exists.'<br />';
|
|
||||||
|
|
||||||
$this->assertTrue($table_exists);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestTruncate()
|
|
||||||
{
|
|
||||||
$this->db->truncate('create_test');
|
|
||||||
|
|
||||||
$this->assertTrue($this->db->affected_rows() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCommitTransaction()
|
|
||||||
{
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (10, 12, 14)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->commit();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestRollbackTransaction()
|
|
||||||
{
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (182, 96, 43)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->rollback();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPreparedStatements()
|
|
||||||
{
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO "create_test" ("id", "key", "val")
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute(array(1,"booger's", "Gross"));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPrepareExecute()
|
|
||||||
{
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO "create_test" ("id", "key", "val")
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$this->db->prepare_execute($sql, array(
|
|
||||||
2, "works", 'also?'
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPrepareQuery()
|
|
||||||
{
|
|
||||||
$this->assertFalse($this->db->prepare_query('', array()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*public function TestDeleteTable()
|
|
||||||
{
|
|
||||||
//Attempt to delete the table
|
|
||||||
$sql = $this->db->sql->delete_table('create_test');
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Reset
|
|
||||||
$this->tearDown();
|
|
||||||
$this->setUp();
|
|
||||||
|
|
||||||
//Check
|
|
||||||
$table_exists = in_array('create_test', $this->tables);
|
|
||||||
$this->assertFalse($table_exists);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSequences()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_sequences()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetProcedures()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_procedures()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetFunctions()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_functions()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetTriggers()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_triggers()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class MySQLQBTest extends QBTest {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
// Attempt to connect, if there is a test config file
|
|
||||||
if (is_file(QBASE_DIR . "test_config.json"))
|
|
||||||
{
|
|
||||||
$params = json_decode(file_get_contents(QBASE_DIR . "test_config.json"));
|
|
||||||
$params = $params->mysql;
|
|
||||||
$params->type = "mysql";
|
|
||||||
|
|
||||||
$this->db = new Query_Builder($params);
|
|
||||||
|
|
||||||
// echo '<hr /> MySQL Queries <hr />';
|
|
||||||
}
|
|
||||||
elseif (($var = getenv('CI')))
|
|
||||||
{
|
|
||||||
$params = array(
|
|
||||||
'host' => '127.0.0.1',
|
|
||||||
'port' => '3306',
|
|
||||||
'database' => 'test',
|
|
||||||
'user' => 'root',
|
|
||||||
'pass' => NULL,
|
|
||||||
'type' => 'mysql'
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->db = new Query_Builder($params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestExists()
|
|
||||||
{
|
|
||||||
$this->assertTrue(in_array('mysql', pdo_drivers()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,195 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MySQLTest class.
|
|
||||||
*
|
|
||||||
* @extends UnitTestCase
|
|
||||||
*/
|
|
||||||
class MySQLTest extends DBTest {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
// Attempt to connect, if there is a test config file
|
|
||||||
if (is_file(QBASE_DIR . "test_config.json"))
|
|
||||||
{
|
|
||||||
$params = json_decode(file_get_contents(QBASE_DIR . "test_config.json"), TRUE);
|
|
||||||
$params = $params['mysql'];
|
|
||||||
|
|
||||||
$this->db = new MySQL("host={$params['host']};port={$params['port']};dbname={$params['database']}", $params['user'], $params['pass']);
|
|
||||||
}
|
|
||||||
elseif (($var = getenv('CI')))
|
|
||||||
{
|
|
||||||
$this->db = new MySQL('host=127.0.0.1;port=3306;dbname=test', 'root');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestExists()
|
|
||||||
{
|
|
||||||
$this->assertTrue(in_array('mysql', pdo_drivers()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestConnection()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$this->assertIsA($this->db, 'MySQL');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCreateTable()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->util->create_table('create_test',
|
|
||||||
array(
|
|
||||||
'id' => 'int(10)',
|
|
||||||
'key' => 'TEXT',
|
|
||||||
'val' => 'TEXT',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'id' => 'PRIMARY KEY'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->util->create_table('create_join',
|
|
||||||
array(
|
|
||||||
'id' => 'int(10)',
|
|
||||||
'key' => 'TEXT',
|
|
||||||
'val' => 'TEXT',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'id' => 'PRIMARY KEY'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Check
|
|
||||||
$dbs = $this->db->get_tables();
|
|
||||||
|
|
||||||
$this->assertTrue(in_array('create_test', $dbs));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestTruncate()
|
|
||||||
{
|
|
||||||
$this->db->truncate('create_test');
|
|
||||||
$this->db->truncate('create_join');
|
|
||||||
|
|
||||||
$ct_query = $this->db->query('SELECT * FROM create_test');
|
|
||||||
$cj_query = $this->db->query('SELECT * FROM create_join');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPreparedStatements()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO `create_test` (`id`, `key`, `val`)
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$statement = $this->db->prepare_query($sql, array(1,"boogers", "Gross"));
|
|
||||||
|
|
||||||
$statement->execute();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPrepareExecute()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO `create_test` (`id`, `key`, `val`)
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$this->db->prepare_execute($sql, array(
|
|
||||||
2, "works", 'also?'
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCommitTransaction()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO `create_test` (`id`, `key`, `val`) VALUES (10, 12, 14)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->commit();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestRollbackTransaction()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO `create_test` (`id`, `key`, `val`) VALUES (182, 96, 43)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->rollback();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSchemas()
|
|
||||||
{
|
|
||||||
$this->assertFalse($this->db->get_schemas());
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetsProcedures()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_procedures()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetTriggers()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_triggers()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSequences()
|
|
||||||
{
|
|
||||||
$this->assertFalse($this->db->get_sequences());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* OpenSQLManager
|
|
||||||
*
|
|
||||||
* Free Database manager for Open Source Databases
|
|
||||||
*
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/OpenSQLManager
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class PgSQLQBTest extends QBTest {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
// Attempt to connect, if there is a test config file
|
|
||||||
if (is_file(QBASE_DIR . "test_config.json"))
|
|
||||||
{
|
|
||||||
$params = json_decode(file_get_contents(QBASE_DIR . "test_config.json"));
|
|
||||||
$params = $params->pgsql;
|
|
||||||
$params->type = "pgsql";
|
|
||||||
|
|
||||||
$this->db = new Query_Builder($params);
|
|
||||||
|
|
||||||
// echo '<hr /> Postgres Queries <hr />';
|
|
||||||
|
|
||||||
}
|
|
||||||
elseif (($var = getenv('CI')))
|
|
||||||
{
|
|
||||||
$params = array(
|
|
||||||
'host' => '127.0.0.1',
|
|
||||||
'port' => '5432',
|
|
||||||
'database' => 'test',
|
|
||||||
'user' => 'postgres',
|
|
||||||
'pass' => '',
|
|
||||||
'type' => 'pgsql'
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->db = new Query_Builder($params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestExists()
|
|
||||||
{
|
|
||||||
$this->assertTrue(in_array('pgsql', pdo_drivers()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,213 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* OpenSQLManager
|
|
||||||
*
|
|
||||||
* Free Database manager for Open Source Databases
|
|
||||||
*
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/OpenSQLManager
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PgTest class.
|
|
||||||
*
|
|
||||||
* @extends UnitTestCase
|
|
||||||
*/
|
|
||||||
class PgTest extends DBTest {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
// Attempt to connect, if there is a test config file
|
|
||||||
if (is_file(QBASE_DIR . "test_config.json"))
|
|
||||||
{
|
|
||||||
$params = json_decode(file_get_contents(QBASE_DIR . "test_config.json"));
|
|
||||||
$params = $params->pgsql;
|
|
||||||
|
|
||||||
$this->db = new PgSQL("host={$params->host};port={$params->port};dbname={$params->database}", $params->user, $params->pass);
|
|
||||||
}
|
|
||||||
elseif (($var = getenv('CI')))
|
|
||||||
{
|
|
||||||
$this->db = new PgSQL('host=127.0.0.1;port=5432;dbname=test', 'postgres');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestExists()
|
|
||||||
{
|
|
||||||
$this->assertTrue(in_array('pgsql', pdo_drivers()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestConnection()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$this->assertIsA($this->db, 'PgSQL');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCreateTable()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
// Drop the table(s) if they exist
|
|
||||||
$sql = 'DROP TABLE IF EXISTS "create_test"';
|
|
||||||
$this->db->query($sql);
|
|
||||||
$sql = 'DROP TABLE IF EXISTS "create_join"';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->util->create_table('create_test',
|
|
||||||
array(
|
|
||||||
'id' => 'integer',
|
|
||||||
'key' => 'TEXT',
|
|
||||||
'val' => 'TEXT',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'id' => 'PRIMARY KEY'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->util->create_table('create_join',
|
|
||||||
array(
|
|
||||||
'id' => 'integer',
|
|
||||||
'key' => 'TEXT',
|
|
||||||
'val' => 'TEXT',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'id' => 'PRIMARY KEY'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//echo $sql.'<br />';
|
|
||||||
|
|
||||||
//Reset
|
|
||||||
unset($this->db);
|
|
||||||
$this->setUp();
|
|
||||||
|
|
||||||
//Check
|
|
||||||
$dbs = $this->db->get_tables();
|
|
||||||
$this->assertTrue(in_array('create_test', $dbs));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestTruncate()
|
|
||||||
{
|
|
||||||
$this->db->truncate('create_test');
|
|
||||||
$this->db->truncate('create_join');
|
|
||||||
|
|
||||||
$ct_query = $this->db->query('SELECT * FROM create_test');
|
|
||||||
$cj_query = $this->db->query('SELECT * FROM create_join');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPreparedStatements()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO "create_test" ("id", "key", "val")
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$statement = $this->db->prepare_query($sql, array(1,"boogers", "Gross"));
|
|
||||||
|
|
||||||
$statement->execute();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPrepareExecute()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO "create_test" ("id", "key", "val")
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$this->db->prepare_execute($sql, array(
|
|
||||||
2, "works", 'also?'
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCommitTransaction()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (10, 12, 14)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->commit();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestRollbackTransaction()
|
|
||||||
{
|
|
||||||
if (empty($this->db)) return;
|
|
||||||
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (182, 96, 43)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->rollback();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSchemas()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_schemas()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSequences()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_sequences()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetsProcedures()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_procedures()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetTriggers()
|
|
||||||
{
|
|
||||||
$this->assertTrue(is_array($this->db->get_triggers()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* OpenSQLManager
|
|
||||||
*
|
|
||||||
* Free Database manager for Open Source Databases
|
|
||||||
*
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/OpenSQLManager
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for testing Query Builder with SQLite
|
|
||||||
*/
|
|
||||||
class SQLiteQBTest extends QBTest {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$path = QTEST_DIR.QDS.'db_files'.QDS.'test_sqlite.db';
|
|
||||||
$params = new Stdclass();
|
|
||||||
$params->type = 'sqlite';
|
|
||||||
$params->file = $path;
|
|
||||||
$params->host = 'localhost';
|
|
||||||
$this->db = new Query_Builder($params);
|
|
||||||
|
|
||||||
// echo '<hr /> SQLite Queries <hr />';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,203 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* OpenSQLManager
|
|
||||||
*
|
|
||||||
* Free Database manager for Open Source Databases
|
|
||||||
*
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/OpenSQLManager
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLiteTest class.
|
|
||||||
*
|
|
||||||
* @extends UnitTestCase
|
|
||||||
*/
|
|
||||||
class SQLiteTest extends UnitTestCase {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
$path = QTEST_DIR.QDS.'db_files'.QDS.'test_sqlite.db';
|
|
||||||
$this->db = new SQLite($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function tearDown()
|
|
||||||
{
|
|
||||||
unset($this->db);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestConnection()
|
|
||||||
{
|
|
||||||
$this->assertIsA($this->db, 'SQLite');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetTables()
|
|
||||||
{
|
|
||||||
$tables = $this->db->get_tables();
|
|
||||||
$this->assertTrue(is_array($tables));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSystemTables()
|
|
||||||
{
|
|
||||||
$tables = $this->db->get_system_tables();
|
|
||||||
|
|
||||||
$this->assertTrue(is_array($tables));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCreateTransaction()
|
|
||||||
{
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCreateTable()
|
|
||||||
{
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->util->create_table('create_test',
|
|
||||||
array(
|
|
||||||
'id' => 'INTEGER',
|
|
||||||
'key' => 'TEXT',
|
|
||||||
'val' => 'TEXT',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'id' => 'PRIMARY KEY'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Attempt to create the table
|
|
||||||
$sql = $this->db->util->create_table('create_join',
|
|
||||||
array(
|
|
||||||
'id' => 'INTEGER',
|
|
||||||
'key' => 'TEXT',
|
|
||||||
'val' => 'TEXT',
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'id' => 'PRIMARY KEY'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Check
|
|
||||||
$dbs = $this->db->get_tables();
|
|
||||||
|
|
||||||
$this->assertTrue(in_array('create_test', $dbs));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestTruncate()
|
|
||||||
{
|
|
||||||
$this->db->truncate('create_test');
|
|
||||||
$this->assertIsA($this->db->affected_rows(), 'int');
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPreparedStatements()
|
|
||||||
{
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO "create_test" ("id", "key", "val")
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$statement = $this->db->prepare_query($sql, array(1,"boogers", "Gross"));
|
|
||||||
|
|
||||||
$statement->execute();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestPrepareExecute()
|
|
||||||
{
|
|
||||||
$sql = <<<SQL
|
|
||||||
INSERT INTO "create_test" ("id", "key", "val")
|
|
||||||
VALUES (?,?,?)
|
|
||||||
SQL;
|
|
||||||
$this->db->prepare_execute($sql, array(
|
|
||||||
2, "works", 'also?'
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestCommitTransaction()
|
|
||||||
{
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (10, 12, 14)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->commit();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestRollbackTransaction()
|
|
||||||
{
|
|
||||||
$res = $this->db->beginTransaction();
|
|
||||||
|
|
||||||
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (182, 96, 43)';
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
$res = $this->db->rollback();
|
|
||||||
$this->assertTrue($res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// This is really time intensive ! Run only when needed
|
|
||||||
/*public function TestDeleteTable()
|
|
||||||
{
|
|
||||||
//Make sure the table exists to delete
|
|
||||||
$dbs = $this->db->get_tables();
|
|
||||||
$this->assertTrue(isset($dbs['create_test']));
|
|
||||||
|
|
||||||
//Attempt to delete the table
|
|
||||||
$sql = $this->db->sql->delete_table('create_test');
|
|
||||||
$this->db->query($sql);
|
|
||||||
|
|
||||||
//Check
|
|
||||||
$dbs = $this->db->get_tables();
|
|
||||||
$this->assertFalse(in_array('create_test', $dbs));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetDBs()
|
|
||||||
{
|
|
||||||
$this->assertFalse($this->db->get_dbs());
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function TestGetSchemas()
|
|
||||||
{
|
|
||||||
$this->assertFalse($this->db->get_schemas());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Query
|
|
||||||
*
|
|
||||||
* Free Query Builder / Database Abstraction Layer
|
|
||||||
*
|
|
||||||
* @package Query
|
|
||||||
* @author Timothy J. Warren
|
|
||||||
* @copyright Copyright (c) 2012
|
|
||||||
* @link https://github.com/aviat4ion/Query
|
|
||||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit test bootstrap - Using php simpletest
|
|
||||||
*/
|
|
||||||
define('QTEST_DIR', dirname(__FILE__));
|
|
||||||
define('QBASE_DIR', str_replace(basename(QTEST_DIR), '', QTEST_DIR));
|
|
||||||
define('QDS', DIRECTORY_SEPARATOR);
|
|
||||||
|
|
||||||
// Include simpletest
|
|
||||||
// it has to be set in your php path, or put in the tests folder
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
// Include db classes
|
|
||||||
require_once(QBASE_DIR . 'autoload.php');
|
|
||||||
|
|
||||||
// Require base testing classes
|
|
||||||
require_once(QTEST_DIR . '/core/core.php');
|
|
||||||
require_once(QTEST_DIR . '/core/settings.php');
|
|
||||||
require_once(QTEST_DIR . '/core/db_test.php');
|
|
||||||
require_once(QTEST_DIR . '/core/db_qb_test.php');
|
|
||||||
|
|
||||||
// Include db tests
|
|
||||||
// Load db classes based on capability
|
|
||||||
$src_path = QBASE_DIR.'drivers/';
|
|
||||||
$test_path = QTEST_DIR.'/databases/';
|
|
||||||
|
|
||||||
foreach(pdo_drivers() as $d)
|
|
||||||
{
|
|
||||||
// PDO firebird isn't stable enough to
|
|
||||||
// bother, so skip it.
|
|
||||||
if ($d === 'firebird')
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$src_dir = "{$test_path}{$d}";
|
|
||||||
|
|
||||||
if(is_dir($src_dir))
|
|
||||||
{
|
|
||||||
require_once("{$test_path}{$d}/{$d}.php");
|
|
||||||
require_once("{$test_path}{$d}/{$d}-qb.php");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load Firebird if there is support
|
|
||||||
if(function_exists('fbird_connect'))
|
|
||||||
{
|
|
||||||
require_once("{$test_path}/firebird/firebird.php");
|
|
||||||
require_once("{$test_path}/firebird/firebird-qb.php");
|
|
||||||
}
|
|
@ -1,399 +0,0 @@
|
|||||||
Simple Test interface changes
|
|
||||||
=============================
|
|
||||||
Because the SimpleTest tool set is still evolving it is likely that tests
|
|
||||||
written with earlier versions will fail with the newest ones. The most
|
|
||||||
dramatic changes are in the alpha releases. Here is a list of possible
|
|
||||||
problems and their fixes...
|
|
||||||
|
|
||||||
assertText() no longer finds a string inside a <script> tag
|
|
||||||
-----------------------------------------------------------
|
|
||||||
The assertText() method is intended to match only visible,
|
|
||||||
human-readable text on the web page. Therefore, the contents of script
|
|
||||||
tags should not be matched by this assertion. However there was a bug
|
|
||||||
in the text normalisation code of simpletest which meant that <script>
|
|
||||||
tags spanning multiple lines would not have their content stripped
|
|
||||||
out. If you want to check the content of a <script> tag, use
|
|
||||||
assertPattern(), or write a custom expectation.
|
|
||||||
|
|
||||||
Overloaded method not working
|
|
||||||
-----------------------------
|
|
||||||
All protected and private methods had underscores
|
|
||||||
removed. This means that any private/protected methods that
|
|
||||||
you overloaded with those names need to be updated.
|
|
||||||
|
|
||||||
Fatal error: Call to undefined method Classname::classname()
|
|
||||||
------------------------------------------------------------
|
|
||||||
SimpleTest renamed all of its constructors from
|
|
||||||
Classname to __construct; derived classes invoking
|
|
||||||
their parent constructors should replace parent::Classname()
|
|
||||||
with parent::__construct().
|
|
||||||
|
|
||||||
Custom CSS in HtmlReporter not being applied
|
|
||||||
--------------------------------------------
|
|
||||||
Batch rename of protected and private methods
|
|
||||||
means that _getCss() was renamed to getCss().
|
|
||||||
Please rename your method and it should work again.
|
|
||||||
|
|
||||||
setReturnReference() throws errors in E_STRICT
|
|
||||||
----------------------------------------------
|
|
||||||
Happens when an object is passed by reference.
|
|
||||||
This also happens with setReturnReferenceAt().
|
|
||||||
If you want to return objects then replace these
|
|
||||||
with calls to returns() and returnsAt() with the
|
|
||||||
same arguments. This change was forced in the 1.1
|
|
||||||
version for E_STRICT compatibility.
|
|
||||||
|
|
||||||
assertReference() throws errors in E_STRICT
|
|
||||||
-------------------------------------------
|
|
||||||
Due to language restrictions you cannot compare
|
|
||||||
both variables and objects in E_STRICT mode. Use
|
|
||||||
assertSame() in this mode with objects. This change
|
|
||||||
was forced the 1.1 version.
|
|
||||||
|
|
||||||
Cannot create GroupTest
|
|
||||||
-----------------------
|
|
||||||
The GroupTest has been renamed TestSuite (see below).
|
|
||||||
It was removed completely in 1.1 in favour of this
|
|
||||||
name.
|
|
||||||
|
|
||||||
No method getRelativeUrls() or getAbsoluteUrls()
|
|
||||||
------------------------------------------------
|
|
||||||
These methods were always a bit weird anyway, and
|
|
||||||
the new parsing of the base tag makes them more so.
|
|
||||||
They have been replaced with getUrls() instead. If
|
|
||||||
you want the old functionality then simply chop
|
|
||||||
off the current domain from getUrls().
|
|
||||||
|
|
||||||
Method setWildcard() removed in mocks
|
|
||||||
-------------------------------------
|
|
||||||
Even setWildcard() has been removed in 1.0.1beta now.
|
|
||||||
If you want to test explicitely for a '*' string, then
|
|
||||||
simply pass in new IdenticalExpectation('*') instead.
|
|
||||||
|
|
||||||
No method _getTest() on mocks
|
|
||||||
-----------------------------
|
|
||||||
This has finally been removed. It was a pretty esoteric
|
|
||||||
flex point anyway. It was there to allow the mocks to
|
|
||||||
work with other test tools, but no one does this.
|
|
||||||
|
|
||||||
No method assertError(), assertNoErrors(), swallowErrors()
|
|
||||||
----------------------------------------------------------
|
|
||||||
These have been deprecated in 1.0.1beta in favour of
|
|
||||||
expectError() and expectException(). assertNoErrors() is
|
|
||||||
redundant if you use expectError() as failures are now reported
|
|
||||||
immediately.
|
|
||||||
|
|
||||||
No method TestCase::signal()
|
|
||||||
----------------------------
|
|
||||||
This has been deprecated in favour of triggering an error or
|
|
||||||
throwing an exception. Deprecated as of 1.0.1beta.
|
|
||||||
|
|
||||||
No method TestCase::sendMessage()
|
|
||||||
---------------------------------
|
|
||||||
This has been deprecated as of 1.0.1beta.
|
|
||||||
|
|
||||||
Failure to connect now emits failures
|
|
||||||
-------------------------------------
|
|
||||||
It used to be that you would have to use the
|
|
||||||
getTransferError() call on the web tester to see if
|
|
||||||
there was a socket level error in a fetch. This check
|
|
||||||
is now always carried out by the WebTestCase unless
|
|
||||||
the fetch is prefaced with WebTestCase::ignoreErrors().
|
|
||||||
The ignore directive only lasts for the next fetching
|
|
||||||
action such as get() and click().
|
|
||||||
|
|
||||||
No method SimpleTestOptions::ignore()
|
|
||||||
-------------------------------------
|
|
||||||
This is deprecated in version 1.0.1beta and has been moved
|
|
||||||
to SimpleTest::ignore() as that is more readable. In
|
|
||||||
addition, parent classes are also ignored automatically.
|
|
||||||
If you are using PHP5 you can skip this directive simply
|
|
||||||
by marking your test case as abstract.
|
|
||||||
|
|
||||||
No method assertCopy()
|
|
||||||
----------------------
|
|
||||||
This is deprecated in 1.0.1 in favour of assertClone().
|
|
||||||
The assertClone() method is slightly different in that
|
|
||||||
the objects must be identical, but without being a
|
|
||||||
reference. It is thus not a strict inversion of
|
|
||||||
assertReference().
|
|
||||||
|
|
||||||
Constructor wildcard override has no effect in mocks
|
|
||||||
----------------------------------------------------
|
|
||||||
As of 1.0.1beta this is now set with setWildcard() instead
|
|
||||||
of in the constructor.
|
|
||||||
|
|
||||||
No methods setStubBaseClass()/getStubBaseClass()
|
|
||||||
------------------------------------------------
|
|
||||||
As mocks are now used instead of stubs, these methods
|
|
||||||
stopped working and are now removed as of the 1.0.1beta
|
|
||||||
release. The mock objects may be freely used instead.
|
|
||||||
|
|
||||||
No method addPartialMockCode()
|
|
||||||
------------------------------
|
|
||||||
The ability to insert arbitrary partial mock code
|
|
||||||
has been removed. This was a low value feature
|
|
||||||
causing needless complications. It was removed
|
|
||||||
in the 1.0.1beta release.
|
|
||||||
|
|
||||||
No method setMockBaseClass()
|
|
||||||
----------------------------
|
|
||||||
The ability to change the mock base class has been
|
|
||||||
scheduled for removal and is deprecated since the
|
|
||||||
1.0.1beta version. This was a rarely used feature
|
|
||||||
except as a workaround for PHP5 limitations. As
|
|
||||||
these limitations are being resolved it's hoped
|
|
||||||
that the bundled mocks can be used directly.
|
|
||||||
|
|
||||||
No class Stub
|
|
||||||
-------------
|
|
||||||
Server stubs are deprecated from 1.0.1 as the mocks now
|
|
||||||
have exactly the same interface. Just use mock objects
|
|
||||||
instead.
|
|
||||||
|
|
||||||
No class SimpleTestOptions
|
|
||||||
--------------------------
|
|
||||||
This was replced by the shorter SimpleTest in 1.0.1beta1
|
|
||||||
and is since deprecated.
|
|
||||||
|
|
||||||
No file simple_test.php
|
|
||||||
-----------------------
|
|
||||||
This was renamed test_case.php in 1.0.1beta to more accurately
|
|
||||||
reflect it's purpose. This file should never be directly
|
|
||||||
included in test suites though, as it's part of the
|
|
||||||
underlying mechanics and has a tendency to be refactored.
|
|
||||||
|
|
||||||
No class WantedPatternExpectation
|
|
||||||
---------------------------------
|
|
||||||
This was deprecated in 1.0.1alpha in favour of the simpler
|
|
||||||
name PatternExpectation.
|
|
||||||
|
|
||||||
No class NoUnwantedPatternExpectation
|
|
||||||
-------------------------------------
|
|
||||||
This was deprecated in 1.0.1alpha in favour of the simpler
|
|
||||||
name NoPatternExpectation.
|
|
||||||
|
|
||||||
No method assertNoUnwantedPattern()
|
|
||||||
-----------------------------------
|
|
||||||
This has been renamed to assertNoPattern() in 1.0.1alpha and
|
|
||||||
the old form is deprecated.
|
|
||||||
|
|
||||||
No method assertWantedPattern()
|
|
||||||
-------------------------------
|
|
||||||
This has been renamed to assertPattern() in 1.0.1alpha and
|
|
||||||
the old form is deprecated.
|
|
||||||
|
|
||||||
No method assertExpectation()
|
|
||||||
-----------------------------
|
|
||||||
This was renamed as assert() in 1.0.1alpha and the old form
|
|
||||||
has been deprecated.
|
|
||||||
|
|
||||||
No class WildcardExpectation
|
|
||||||
----------------------------
|
|
||||||
This was a mostly internal class for the mock objects. It was
|
|
||||||
renamed AnythingExpectation to bring it closer to JMock and
|
|
||||||
NMock in version 1.0.1alpha.
|
|
||||||
|
|
||||||
Missing UnitTestCase::assertErrorPattern()
|
|
||||||
------------------------------------------
|
|
||||||
This method is deprecated for version 1.0.1 onwards.
|
|
||||||
This method has been subsumed by assertError() that can now
|
|
||||||
take an expectation. Simply pass a PatternExpectation
|
|
||||||
into assertError() to simulate the old behaviour.
|
|
||||||
|
|
||||||
No HTML when matching page elements
|
|
||||||
-----------------------------------
|
|
||||||
This behaviour has been switched to using plain text as if it
|
|
||||||
were seen by the user of the browser. This means that HTML tags
|
|
||||||
are suppressed, entities are converted and whitespace is
|
|
||||||
normalised. This should make it easier to match items in forms.
|
|
||||||
Also images are replaced with their "alt" text so that they
|
|
||||||
can be matched as well.
|
|
||||||
|
|
||||||
No method SimpleRunner::_getTestCase()
|
|
||||||
--------------------------------------
|
|
||||||
This was made public as getTestCase() in 1.0RC2.
|
|
||||||
|
|
||||||
No method restartSession()
|
|
||||||
--------------------------
|
|
||||||
This was renamed to restart() in the WebTestCase, SimpleBrowser
|
|
||||||
and the underlying SimpleUserAgent in 1.0RC2. Because it was
|
|
||||||
undocumented anyway, no attempt was made at backward
|
|
||||||
compatibility.
|
|
||||||
|
|
||||||
My custom test case ignored by tally()
|
|
||||||
--------------------------------------
|
|
||||||
The _assertTrue method has had it's signature changed due to a bug
|
|
||||||
in the PHP 5.0.1 release. You must now use getTest() from within
|
|
||||||
that method to get the test case. Mock compatibility with other
|
|
||||||
unit testers is now deprecated as of 1.0.1alpha as PEAR::PHPUnit2
|
|
||||||
should soon have mock support of it's own.
|
|
||||||
|
|
||||||
Broken code extending SimpleRunner
|
|
||||||
----------------------------------
|
|
||||||
This was replaced with SimpleScorer so that I could use the runner
|
|
||||||
name in another class. This happened in RC1 development and there
|
|
||||||
is no easy backward compatibility fix. The solution is simply to
|
|
||||||
extend SimpleScorer instead.
|
|
||||||
|
|
||||||
Missing method getBaseCookieValue()
|
|
||||||
-----------------------------------
|
|
||||||
This was renamed getCurrentCookieValue() in RC1.
|
|
||||||
|
|
||||||
Missing files from the SimpleTest suite
|
|
||||||
---------------------------------------
|
|
||||||
Versions of SimpleTest prior to Beta6 required a SIMPLE_TEST constant
|
|
||||||
to point at the SimpleTest folder location before any of the toolset
|
|
||||||
was loaded. This is no longer documented as it is now unnecessary
|
|
||||||
for later versions. If you are using an earlier version you may
|
|
||||||
need this constant. Consult the documentation that was bundled with
|
|
||||||
the release that you are using or upgrade to Beta6 or later.
|
|
||||||
|
|
||||||
No method SimpleBrowser::getCurrentUrl()
|
|
||||||
--------------------------------------
|
|
||||||
This is replaced with the more versatile showRequest() for
|
|
||||||
debugging. It only existed in this context for version Beta5.
|
|
||||||
Later versions will have SimpleBrowser::getHistory() for tracking
|
|
||||||
paths through pages. It is renamed as getUrl() since 1.0RC1.
|
|
||||||
|
|
||||||
No method Stub::setStubBaseClass()
|
|
||||||
----------------------------------
|
|
||||||
This method has finally been removed in 1.0RC1. Use
|
|
||||||
SimpleTestOptions::setStubBaseClass() instead.
|
|
||||||
|
|
||||||
No class CommandLineReporter
|
|
||||||
----------------------------
|
|
||||||
This was renamed to TextReporter in Beta3 and the deprecated version
|
|
||||||
was removed in 1.0RC1.
|
|
||||||
|
|
||||||
No method requireReturn()
|
|
||||||
-------------------------
|
|
||||||
This was deprecated in Beta3 and is now removed.
|
|
||||||
|
|
||||||
No method expectCookie()
|
|
||||||
------------------------
|
|
||||||
This method was abruptly removed in Beta4 so as to simplify the internals
|
|
||||||
until another mechanism can replace it. As a workaround it is necessary
|
|
||||||
to assert that the cookie has changed by setting it before the page
|
|
||||||
fetch and then assert the desired value.
|
|
||||||
|
|
||||||
No method clickSubmitByFormId()
|
|
||||||
-------------------------------
|
|
||||||
This method had an incorrect name as no button was involved. It was
|
|
||||||
renamed to submitByFormId() in Beta4 and the old version deprecated.
|
|
||||||
Now removed.
|
|
||||||
|
|
||||||
No method paintStart() or paintEnd()
|
|
||||||
------------------------------------
|
|
||||||
You should only get this error if you have subclassed the lower level
|
|
||||||
reporting and test runner machinery. These methods have been broken
|
|
||||||
down into events for test methods, events for test cases and events
|
|
||||||
for group tests. The new methods are...
|
|
||||||
|
|
||||||
paintStart() --> paintMethodStart(), paintCaseStart(), paintGroupStart()
|
|
||||||
paintEnd() --> paintMethodEnd(), paintCaseEnd(), paintGroupEnd()
|
|
||||||
|
|
||||||
This change was made in Beta3, ironically to make it easier to subclass
|
|
||||||
the inner machinery. Simply duplicating the code you had in the previous
|
|
||||||
methods should provide a temporary fix.
|
|
||||||
|
|
||||||
No class TestDisplay
|
|
||||||
--------------------
|
|
||||||
This has been folded into SimpleReporter in Beta3 and is now deprecated.
|
|
||||||
It was removed in RC1.
|
|
||||||
|
|
||||||
No method WebTestCase::fetch()
|
|
||||||
------------------------------
|
|
||||||
This was renamed get() in Alpha8. It is removed in Beta3.
|
|
||||||
|
|
||||||
No method submit()
|
|
||||||
------------------
|
|
||||||
This has been renamed clickSubmit() in Beta1. The old method was
|
|
||||||
removed in Beta2.
|
|
||||||
|
|
||||||
No method clearHistory()
|
|
||||||
------------------------
|
|
||||||
This method is deprecated in Beta2 and removed in RC1.
|
|
||||||
|
|
||||||
No method getCallCount()
|
|
||||||
------------------------
|
|
||||||
This method has been deprecated since Beta1 and has now been
|
|
||||||
removed. There are now more ways to set expectations on counts
|
|
||||||
and so this method should be unecessery. Removed in RC1.
|
|
||||||
|
|
||||||
Cannot find file *
|
|
||||||
------------------
|
|
||||||
The following public name changes have occoured...
|
|
||||||
|
|
||||||
simple_html_test.php --> reporter.php
|
|
||||||
simple_mock.php --> mock_objects.php
|
|
||||||
simple_unit.php --> unit_tester.php
|
|
||||||
simple_web.php --> web_tester.php
|
|
||||||
|
|
||||||
The old names were deprecated in Alpha8 and removed in Beta1.
|
|
||||||
|
|
||||||
No method attachObserver()
|
|
||||||
--------------------------
|
|
||||||
Prior to the Alpha8 release the old internal observer pattern was
|
|
||||||
gutted and replaced with a visitor. This is to trade flexibility of
|
|
||||||
test case expansion against the ease of writing user interfaces.
|
|
||||||
|
|
||||||
Code such as...
|
|
||||||
|
|
||||||
$test = &new MyTestCase();
|
|
||||||
$test->attachObserver(new TestHtmlDisplay());
|
|
||||||
$test->run();
|
|
||||||
|
|
||||||
...should be rewritten as...
|
|
||||||
|
|
||||||
$test = &new MyTestCase();
|
|
||||||
$test->run(new HtmlReporter());
|
|
||||||
|
|
||||||
If you previously attached multiple observers then the workaround
|
|
||||||
is to run the tests twice, once with each, until they can be combined.
|
|
||||||
For one observer the old method is simulated in Alpha 8, but is
|
|
||||||
removed in Beta1.
|
|
||||||
|
|
||||||
No class TestHtmlDisplay
|
|
||||||
------------------------
|
|
||||||
This class has been renamed to HtmlReporter in Alpha8. It is supported,
|
|
||||||
but deprecated in Beta1 and removed in Beta2. If you have subclassed
|
|
||||||
the display for your own design, then you will have to extend this
|
|
||||||
class (HtmlReporter) instead.
|
|
||||||
|
|
||||||
If you have accessed the event queue by overriding the notify() method
|
|
||||||
then I am afraid you are in big trouble :(. The reporter is now
|
|
||||||
carried around the test suite by the runner classes and the methods
|
|
||||||
called directly. In the unlikely event that this is a problem and
|
|
||||||
you don't want to upgrade the test tool then simplest is to write your
|
|
||||||
own runner class and invoke the tests with...
|
|
||||||
|
|
||||||
$test->accept(new MyRunner(new MyReporter()));
|
|
||||||
|
|
||||||
...rather than the run method. This should be easier to extend
|
|
||||||
anyway and gives much more control. Even this method is overhauled
|
|
||||||
in Beta3 where the runner class can be set within the test case. Really
|
|
||||||
the best thing to do is to upgrade to this version as whatever you were
|
|
||||||
trying to achieve before should now be very much easier.
|
|
||||||
|
|
||||||
Missing set options method
|
|
||||||
--------------------------
|
|
||||||
All test suite options are now in one class called SimpleTestOptions.
|
|
||||||
This means that options are set differently...
|
|
||||||
|
|
||||||
GroupTest::ignore() --> SimpleTestOptions::ignore()
|
|
||||||
Mock::setMockBaseClass() --> SimpleTestOptions::setMockBaseClass()
|
|
||||||
|
|
||||||
These changed in Alpha8 and the old versions are now removed in RC1.
|
|
||||||
|
|
||||||
No method setExpected*()
|
|
||||||
------------------------
|
|
||||||
The mock expectations changed their names in Alpha4 and the old names
|
|
||||||
ceased to be supported in Alpha8. The changes are...
|
|
||||||
|
|
||||||
setExpectedArguments() --> expectArguments()
|
|
||||||
setExpectedArgumentsSequence() --> expectArgumentsAt()
|
|
||||||
setExpectedCallCount() --> expectCallCount()
|
|
||||||
setMaximumCallCount() --> expectMaximumCallCount()
|
|
||||||
|
|
||||||
The parameters remained the same.
|
|
@ -1,502 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
|
||||||
you have the freedom to distribute copies of free software (and charge
|
|
||||||
for this service if you wish); that you receive source code or can get
|
|
||||||
it if you want it; that you can change the software and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
|
||||||
allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control compilation
|
|
||||||
and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under any
|
|
||||||
particular circumstance, the balance of the section is intended to apply,
|
|
||||||
and the section as a whole is intended to apply in other circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License may add
|
|
||||||
an explicit geographical distribution limitation excluding those countries,
|
|
||||||
so that distribution is permitted only in or among countries not thus
|
|
||||||
excluded. In such case, this License incorporates the limitation as if
|
|
||||||
written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms of the
|
|
||||||
ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library. It is
|
|
||||||
safest to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
|
||||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
@ -1,102 +0,0 @@
|
|||||||
SimpleTest
|
|
||||||
==========
|
|
||||||
|
|
||||||
You probably got this package from:
|
|
||||||
|
|
||||||
http://simpletest.org/en/download.html
|
|
||||||
|
|
||||||
If there is no licence agreement with this package please download
|
|
||||||
a version from the location above. You must read and accept that
|
|
||||||
licence to use this software. The file is titled simply LICENSE.
|
|
||||||
|
|
||||||
What is it? It's a framework for unit testing, web site testing and
|
|
||||||
mock objects for PHP 5.0.5+.
|
|
||||||
|
|
||||||
If you have used JUnit, you will find this PHP unit testing version very
|
|
||||||
similar. Also included is a mock objects and server stubs generator.
|
|
||||||
The stubs can have return values set for different arguments, can have
|
|
||||||
sequences set also by arguments and can return items by reference.
|
|
||||||
The mocks inherit all of this functionality and can also have
|
|
||||||
expectations set, again in sequences and for different arguments.
|
|
||||||
|
|
||||||
A web tester similar in concept to JWebUnit is also included. There is no
|
|
||||||
JavaScript or tables support, but forms, authentication, cookies and
|
|
||||||
frames are handled.
|
|
||||||
|
|
||||||
You can see a release schedule at http://simpletest.org/en/overview.html
|
|
||||||
which is also copied to the documentation folder with this release.
|
|
||||||
A full PHPDocumenter API documentation exists at
|
|
||||||
http://simpletest.org/api/.
|
|
||||||
|
|
||||||
The user interface is minimal in the extreme, but a lot of information
|
|
||||||
flows from the test suite. After version 1.0 we will release a better
|
|
||||||
web UI, but we are leaving XUL and GTK versions to volunteers as
|
|
||||||
everybody has their own opinion on a good GUI, and we don't want to
|
|
||||||
discourage development by shipping one with the toolkit. You can
|
|
||||||
download an Eclipse plug-in separately.
|
|
||||||
|
|
||||||
The unit tests for SimpleTest itself can be run here:
|
|
||||||
|
|
||||||
test/unit_tests.php
|
|
||||||
|
|
||||||
And tests involving live network connections as well are here:
|
|
||||||
|
|
||||||
test/all_tests.php
|
|
||||||
|
|
||||||
The full tests will typically overrun the 8Mb limit often allowed
|
|
||||||
to a PHP process. A workaround is to run the tests on the command
|
|
||||||
with a custom php.ini file or with the switch -dmemory_limit=-1
|
|
||||||
if you do not have access to your server version.
|
|
||||||
|
|
||||||
The full tests read some test data from simpletest.org. If the site
|
|
||||||
is down or has been modified for a later version then you will get
|
|
||||||
spurious errors. A unit_tests.php failure on the other hand would be
|
|
||||||
very serious. Please notify us if you find one.
|
|
||||||
|
|
||||||
Even if all of the tests run please verify that your existing test suites
|
|
||||||
also function as expected. The file:
|
|
||||||
|
|
||||||
HELP_MY_TESTS_DONT_WORK_ANYMORE
|
|
||||||
|
|
||||||
...contains information on interface changes. It also points out
|
|
||||||
deprecated interfaces, so you should read this even if all of
|
|
||||||
your current tests appear to run.
|
|
||||||
|
|
||||||
There is a documentation folder which contains the core reference information
|
|
||||||
in English and French, although this information is fairly basic.
|
|
||||||
You can find a tutorial on...
|
|
||||||
|
|
||||||
http://simpletest.org/en/first_test_tutorial.html
|
|
||||||
|
|
||||||
...to get you started and this material will eventually become included
|
|
||||||
with the project documentation. A French translation exists at:
|
|
||||||
|
|
||||||
http://simpletest.org/fr/first_test_tutorial.html
|
|
||||||
|
|
||||||
If you download and use, and possibly even extend this tool, please let us
|
|
||||||
know. Any feedback, even bad, is always welcome and we will work to get
|
|
||||||
your suggestions into the next release. Ideally please send your
|
|
||||||
comments to:
|
|
||||||
|
|
||||||
simpletest-support@lists.sourceforge.net
|
|
||||||
|
|
||||||
...so that others can read them too. We usually try to respond within 48
|
|
||||||
hours.
|
|
||||||
|
|
||||||
There is no change log except at Sourceforge. You can visit the
|
|
||||||
release notes to see the completed TODO list after each cycle and also the
|
|
||||||
status of any bugs, but if the bug is recent then it will be fixed in SVN only.
|
|
||||||
The SVN check-ins always have all the tests passing and so SVN snapshots should
|
|
||||||
be pretty usable, although the code may not look so good internally.
|
|
||||||
|
|
||||||
Oh, and one last thing: SimpleTest is called "Simple" because it should
|
|
||||||
be simple to use. We intend to add a complete set of tools for a test
|
|
||||||
first and "test as you code" type of development. "Simple" does not mean
|
|
||||||
"Lite" in this context.
|
|
||||||
|
|
||||||
Thanks to everyone who has sent comments and offered suggestions. They
|
|
||||||
really are invaluable, but sadly you are too many to mention in full.
|
|
||||||
Thanks to all on the advanced PHP forum on SitePoint, especially Harry
|
|
||||||
Fuecks. Early adopters are always an inspiration.
|
|
||||||
|
|
||||||
-- Marcus Baker, Jason Sweat, Travis Swicegood, Perrick Penet and Edward Z. Yang.
|
|
@ -1 +0,0 @@
|
|||||||
1.1.0
|
|
@ -1,224 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* base include file for SimpleTest
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
* @version $Id: dumper.php 1909 2009-07-29 15:58:11Z dgheath $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the command line arguments.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
*/
|
|
||||||
class SimpleArguments {
|
|
||||||
private $all = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the command line arguments. The usual formats
|
|
||||||
* are supported:
|
|
||||||
* -f value
|
|
||||||
* -f=value
|
|
||||||
* --flag=value
|
|
||||||
* --flag value
|
|
||||||
* -f (true)
|
|
||||||
* --flag (true)
|
|
||||||
* @param array $arguments Normally the PHP $argv.
|
|
||||||
*/
|
|
||||||
function __construct($arguments) {
|
|
||||||
array_shift($arguments);
|
|
||||||
while (count($arguments) > 0) {
|
|
||||||
list($key, $value) = $this->parseArgument($arguments);
|
|
||||||
$this->assign($key, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value in the argments object. If multiple
|
|
||||||
* values are added under the same key, the key will
|
|
||||||
* give an array value in the order they were added.
|
|
||||||
* @param string $key The variable to assign to.
|
|
||||||
* @param string value The value that would norally
|
|
||||||
* be colected on the command line.
|
|
||||||
*/
|
|
||||||
function assign($key, $value) {
|
|
||||||
if ($this->$key === false) {
|
|
||||||
$this->all[$key] = $value;
|
|
||||||
} elseif (! is_array($this->$key)) {
|
|
||||||
$this->all[$key] = array($this->$key, $value);
|
|
||||||
} else {
|
|
||||||
$this->all[$key][] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the next key and value from the argument list.
|
|
||||||
* @param array $arguments The remaining arguments to be parsed.
|
|
||||||
* The argument list will be reduced.
|
|
||||||
* @return array Two item array of key and value.
|
|
||||||
* If no value can be found it will
|
|
||||||
* have the value true assigned instead.
|
|
||||||
*/
|
|
||||||
private function parseArgument(&$arguments) {
|
|
||||||
$argument = array_shift($arguments);
|
|
||||||
if (preg_match('/^-(\w)=(.+)$/', $argument, $matches)) {
|
|
||||||
return array($matches[1], $matches[2]);
|
|
||||||
} elseif (preg_match('/^-(\w)$/', $argument, $matches)) {
|
|
||||||
return array($matches[1], $this->nextNonFlagElseTrue($arguments));
|
|
||||||
} elseif (preg_match('/^--(\w+)=(.+)$/', $argument, $matches)) {
|
|
||||||
return array($matches[1], $matches[2]);
|
|
||||||
} elseif (preg_match('/^--(\w+)$/', $argument, $matches)) {
|
|
||||||
return array($matches[1], $this->nextNonFlagElseTrue($arguments));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to use the next argument as a value. It
|
|
||||||
* won't use what it thinks is a flag.
|
|
||||||
* @param array $arguments Remaining arguments to be parsed.
|
|
||||||
* This variable is modified if there
|
|
||||||
* is a value to be extracted.
|
|
||||||
* @return string/boolean The next value unless it's a flag.
|
|
||||||
*/
|
|
||||||
private function nextNonFlagElseTrue(&$arguments) {
|
|
||||||
return $this->valueIsNext($arguments) ? array_shift($arguments) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test to see if the next available argument is a valid value.
|
|
||||||
* If it starts with "-" or "--" it's a flag and doesn't count.
|
|
||||||
* @param array $arguments Remaining arguments to be parsed.
|
|
||||||
* Not affected by this call.
|
|
||||||
* boolean True if valid value.
|
|
||||||
*/
|
|
||||||
function valueIsNext($arguments) {
|
|
||||||
return isset($arguments[0]) && ! $this->isFlag($arguments[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* It's a flag if it starts with "-" or "--".
|
|
||||||
* @param string $argument Value to be tested.
|
|
||||||
* @return boolean True if it's a flag.
|
|
||||||
*/
|
|
||||||
function isFlag($argument) {
|
|
||||||
return strncmp($argument, '-', 1) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The arguments are available as individual member
|
|
||||||
* variables on the object.
|
|
||||||
* @param string $key Argument name.
|
|
||||||
* @return string/array/boolean Either false for no value,
|
|
||||||
* the value as a string or
|
|
||||||
* a list of multiple values if
|
|
||||||
* the flag had been specified more
|
|
||||||
* than once.
|
|
||||||
*/
|
|
||||||
function __get($key) {
|
|
||||||
if (isset($this->all[$key])) {
|
|
||||||
return $this->all[$key];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The entire argument set as a hash.
|
|
||||||
* @return hash Each argument and it's value(s).
|
|
||||||
*/
|
|
||||||
function all() {
|
|
||||||
return $this->all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the help for the command line arguments.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
*/
|
|
||||||
class SimpleHelp {
|
|
||||||
private $overview;
|
|
||||||
private $flag_sets = array();
|
|
||||||
private $explanations = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the top level explanation for the program.
|
|
||||||
* @param string $overview Summary of program.
|
|
||||||
*/
|
|
||||||
function __construct($overview = '') {
|
|
||||||
$this->overview = $overview;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the explanation for a group of flags that all
|
|
||||||
* have the same function.
|
|
||||||
* @param string/array $flags Flag and alternates. Don't
|
|
||||||
* worry about leading dashes
|
|
||||||
* as these are inserted automatically.
|
|
||||||
* @param string $explanation What that flag group does.
|
|
||||||
*/
|
|
||||||
function explainFlag($flags, $explanation) {
|
|
||||||
$flags = is_array($flags) ? $flags : array($flags);
|
|
||||||
$this->flag_sets[] = $flags;
|
|
||||||
$this->explanations[] = $explanation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the help text.
|
|
||||||
* @returns string The complete formatted text.
|
|
||||||
*/
|
|
||||||
function render() {
|
|
||||||
$tab_stop = $this->longestFlag($this->flag_sets) + 4;
|
|
||||||
$text = $this->overview . "\n";
|
|
||||||
for ($i = 0; $i < count($this->flag_sets); $i++) {
|
|
||||||
$text .= $this->renderFlagSet($this->flag_sets[$i], $this->explanations[$i], $tab_stop);
|
|
||||||
}
|
|
||||||
return $this->noDuplicateNewLines($text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Works out the longest flag for formatting purposes.
|
|
||||||
* @param array $flag_sets The internal flag set list.
|
|
||||||
*/
|
|
||||||
private function longestFlag($flag_sets) {
|
|
||||||
$longest = 0;
|
|
||||||
foreach ($flag_sets as $flags) {
|
|
||||||
foreach ($flags as $flag) {
|
|
||||||
$longest = max($longest, strlen($this->renderFlag($flag)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $longest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the text for a single flag and it's alternate flags.
|
|
||||||
* @returns string Help text for that flag group.
|
|
||||||
*/
|
|
||||||
private function renderFlagSet($flags, $explanation, $tab_stop) {
|
|
||||||
$flag = array_shift($flags);
|
|
||||||
$text = str_pad($this->renderFlag($flag), $tab_stop, ' ') . $explanation . "\n";
|
|
||||||
foreach ($flags as $flag) {
|
|
||||||
$text .= ' ' . $this->renderFlag($flag) . "\n";
|
|
||||||
}
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the flag name including leading dashes.
|
|
||||||
* @param string $flag Just the name.
|
|
||||||
* @returns Fag with apropriate dashes.
|
|
||||||
*/
|
|
||||||
private function renderFlag($flag) {
|
|
||||||
return (strlen($flag) == 1 ? '-' : '--') . $flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts multiple new lines into a single new line.
|
|
||||||
* Just there to trap accidental duplicate new lines.
|
|
||||||
* @param string $text Text to clean up.
|
|
||||||
* @returns string Text with no blank lines.
|
|
||||||
*/
|
|
||||||
private function noDuplicateNewLines($text) {
|
|
||||||
return preg_replace('/(\n+)/', "\n", $text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,237 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Base include file for SimpleTest
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage WebTester
|
|
||||||
* @version $Id: authentication.php 2011 2011-04-29 08:22:48Z pp11 $
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* include http class
|
|
||||||
*/
|
|
||||||
require_once(dirname(__FILE__) . '/http.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a single security realm's identity.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage WebTester
|
|
||||||
*/
|
|
||||||
class SimpleRealm {
|
|
||||||
private $type;
|
|
||||||
private $root;
|
|
||||||
private $username;
|
|
||||||
private $password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts with the initial entry directory.
|
|
||||||
* @param string $type Authentication type for this
|
|
||||||
* realm. Only Basic authentication
|
|
||||||
* is currently supported.
|
|
||||||
* @param SimpleUrl $url Somewhere in realm.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function SimpleRealm($type, $url) {
|
|
||||||
$this->type = $type;
|
|
||||||
$this->root = $url->getBasePath();
|
|
||||||
$this->username = false;
|
|
||||||
$this->password = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds another location to the realm.
|
|
||||||
* @param SimpleUrl $url Somewhere in realm.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function stretch($url) {
|
|
||||||
$this->root = $this->getCommonPath($this->root, $url->getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the common starting path.
|
|
||||||
* @param string $first Path to compare.
|
|
||||||
* @param string $second Path to compare.
|
|
||||||
* @return string Common directories.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function getCommonPath($first, $second) {
|
|
||||||
$first = explode('/', $first);
|
|
||||||
$second = explode('/', $second);
|
|
||||||
for ($i = 0; $i < min(count($first), count($second)); $i++) {
|
|
||||||
if ($first[$i] != $second[$i]) {
|
|
||||||
return implode('/', array_slice($first, 0, $i)) . '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return implode('/', $first) . '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the identity to try within this realm.
|
|
||||||
* @param string $username Username in authentication dialog.
|
|
||||||
* @param string $username Password in authentication dialog.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function setIdentity($username, $password) {
|
|
||||||
$this->username = $username;
|
|
||||||
$this->password = $password;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for current identity.
|
|
||||||
* @return string Last succesful username.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getUsername() {
|
|
||||||
return $this->username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for current identity.
|
|
||||||
* @return string Last succesful password.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getPassword() {
|
|
||||||
return $this->password;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test to see if the URL is within the directory
|
|
||||||
* tree of the realm.
|
|
||||||
* @param SimpleUrl $url URL to test.
|
|
||||||
* @return boolean True if subpath.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function isWithin($url) {
|
|
||||||
if ($this->isIn($this->root, $url->getBasePath())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($this->isIn($this->root, $url->getBasePath() . $url->getPage() . '/')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests to see if one string is a substring of
|
|
||||||
* another.
|
|
||||||
* @param string $part Small bit.
|
|
||||||
* @param string $whole Big bit.
|
|
||||||
* @return boolean True if the small bit is
|
|
||||||
* in the big bit.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function isIn($part, $whole) {
|
|
||||||
return strpos($whole, $part) === 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manages security realms.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage WebTester
|
|
||||||
*/
|
|
||||||
class SimpleAuthenticator {
|
|
||||||
private $realms;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the realms.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function SimpleAuthenticator() {
|
|
||||||
$this->restartSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts with no realms set up.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function restartSession() {
|
|
||||||
$this->realms = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new realm centered the current URL.
|
|
||||||
* Browsers privatey wildly on their behaviour in this
|
|
||||||
* regard. Mozilla ignores the realm and presents
|
|
||||||
* only when challenged, wasting bandwidth. IE
|
|
||||||
* just carries on presenting until a new challenge
|
|
||||||
* occours. SimpleTest tries to follow the spirit of
|
|
||||||
* the original standards committee and treats the
|
|
||||||
* base URL as the root of a file tree shaped realm.
|
|
||||||
* @param SimpleUrl $url Base of realm.
|
|
||||||
* @param string $type Authentication type for this
|
|
||||||
* realm. Only Basic authentication
|
|
||||||
* is currently supported.
|
|
||||||
* @param string $realm Name of realm.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function addRealm($url, $type, $realm) {
|
|
||||||
$this->realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current identity to be presented
|
|
||||||
* against that realm.
|
|
||||||
* @param string $host Server hosting realm.
|
|
||||||
* @param string $realm Name of realm.
|
|
||||||
* @param string $username Username for realm.
|
|
||||||
* @param string $password Password for realm.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function setIdentityForRealm($host, $realm, $username, $password) {
|
|
||||||
if (isset($this->realms[$host][$realm])) {
|
|
||||||
$this->realms[$host][$realm]->setIdentity($username, $password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the name of the realm by comparing URLs.
|
|
||||||
* @param SimpleUrl $url URL to test.
|
|
||||||
* @return SimpleRealm Name of realm.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function findRealmFromUrl($url) {
|
|
||||||
if (! isset($this->realms[$url->getHost()])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
foreach ($this->realms[$url->getHost()] as $name => $realm) {
|
|
||||||
if ($realm->isWithin($url)) {
|
|
||||||
return $realm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Presents the appropriate headers for this location.
|
|
||||||
* @param SimpleHttpRequest $request Request to modify.
|
|
||||||
* @param SimpleUrl $url Base of realm.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function addHeaders(&$request, $url) {
|
|
||||||
if ($url->getUsername() && $url->getPassword()) {
|
|
||||||
$username = $url->getUsername();
|
|
||||||
$password = $url->getPassword();
|
|
||||||
} elseif ($realm = $this->findRealmFromUrl($url)) {
|
|
||||||
$username = $realm->getUsername();
|
|
||||||
$password = $realm->getPassword();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$this->addBasicHeaders($request, $username, $password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Presents the appropriate headers for this
|
|
||||||
* location for basic authentication.
|
|
||||||
* @param SimpleHttpRequest $request Request to modify.
|
|
||||||
* @param string $username Username for realm.
|
|
||||||
* @param string $password Password for realm.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
static function addBasicHeaders(&$request, $username, $password) {
|
|
||||||
if ($username && $password) {
|
|
||||||
$request->addHeaderLine(
|
|
||||||
'Authorization: Basic ' . base64_encode("$username:$password"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,101 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Autorunner which runs all tests cases found in a file
|
|
||||||
* that includes this module.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @version $Id: autorun.php 2037 2011-11-30 17:58:21Z pp11 $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* include simpletest files
|
|
||||||
*/
|
|
||||||
require_once dirname(__FILE__) . '/unit_tester.php';
|
|
||||||
require_once dirname(__FILE__) . '/mock_objects.php';
|
|
||||||
require_once dirname(__FILE__) . '/collector.php';
|
|
||||||
require_once dirname(__FILE__) . '/default_reporter.php';
|
|
||||||
/**#@-*/
|
|
||||||
|
|
||||||
$GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_CLASSES'] = get_declared_classes();
|
|
||||||
$GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_PATH'] = getcwd();
|
|
||||||
register_shutdown_function('simpletest_autorun');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit handler to run all recent test cases and exit system if in CLI
|
|
||||||
*/
|
|
||||||
function simpletest_autorun() {
|
|
||||||
chdir($GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_PATH']);
|
|
||||||
if (tests_have_run()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$result = run_local_tests();
|
|
||||||
if (SimpleReporter::inCli()) {
|
|
||||||
exit($result ? 0 : 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* run all recent test cases if no test has
|
|
||||||
* so far been run. Uses the DefaultReporter which can have
|
|
||||||
* it's output controlled with SimpleTest::prefer().
|
|
||||||
* @return boolean/null false if there were test failures, true if
|
|
||||||
* there were no failures, null if tests are
|
|
||||||
* already running
|
|
||||||
*/
|
|
||||||
function run_local_tests() {
|
|
||||||
try {
|
|
||||||
if (tests_have_run()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$candidates = capture_new_classes();
|
|
||||||
$loader = new SimpleFileLoader();
|
|
||||||
$suite = $loader->createSuiteFromClasses(
|
|
||||||
basename(initial_file()),
|
|
||||||
$loader->selectRunnableTests($candidates));
|
|
||||||
return $suite->run(new DefaultReporter());
|
|
||||||
} catch (Exception $stack_frame_fix) {
|
|
||||||
print $stack_frame_fix->getMessage();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the current test context to see if a test has
|
|
||||||
* ever been run.
|
|
||||||
* @return boolean True if tests have run.
|
|
||||||
*/
|
|
||||||
function tests_have_run() {
|
|
||||||
if ($context = SimpleTest::getContext()) {
|
|
||||||
return (boolean)$context->getTest();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The first autorun file.
|
|
||||||
* @return string Filename of first autorun script.
|
|
||||||
*/
|
|
||||||
function initial_file() {
|
|
||||||
static $file = false;
|
|
||||||
if (! $file) {
|
|
||||||
if (isset($_SERVER, $_SERVER['SCRIPT_FILENAME'])) {
|
|
||||||
$file = $_SERVER['SCRIPT_FILENAME'];
|
|
||||||
} else {
|
|
||||||
$included_files = get_included_files();
|
|
||||||
$file = reset($included_files);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Every class since the first autorun include. This
|
|
||||||
* is safe enough if require_once() is always used.
|
|
||||||
* @return array Class names.
|
|
||||||
*/
|
|
||||||
function capture_new_classes() {
|
|
||||||
global $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES;
|
|
||||||
return array_map('strtolower', array_diff(get_declared_classes(),
|
|
||||||
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES ?
|
|
||||||
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES : array()));
|
|
||||||
}
|
|
||||||
?>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,122 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* This file contains the following classes: {@link SimpleCollector},
|
|
||||||
* {@link SimplePatternCollector}.
|
|
||||||
*
|
|
||||||
* @author Travis Swicegood <development@domain51.com>
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
* @version $Id: collector.php 2011 2011-04-29 08:22:48Z pp11 $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The basic collector for {@link GroupTest}
|
|
||||||
*
|
|
||||||
* @see collect(), GroupTest::collect()
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
*/
|
|
||||||
class SimpleCollector {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strips off any kind of slash at the end so as to normalise the path.
|
|
||||||
* @param string $path Path to normalise.
|
|
||||||
* @return string Path without trailing slash.
|
|
||||||
*/
|
|
||||||
protected function removeTrailingSlash($path) {
|
|
||||||
if (substr($path, -1) == DIRECTORY_SEPARATOR) {
|
|
||||||
return substr($path, 0, -1);
|
|
||||||
} elseif (substr($path, -1) == '/') {
|
|
||||||
return substr($path, 0, -1);
|
|
||||||
} else {
|
|
||||||
return $path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans the directory and adds what it can.
|
|
||||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
|
||||||
* @param string $path Directory to scan.
|
|
||||||
* @see _attemptToAdd()
|
|
||||||
*/
|
|
||||||
function collect(&$test, $path) {
|
|
||||||
$path = $this->removeTrailingSlash($path);
|
|
||||||
if ($handle = opendir($path)) {
|
|
||||||
while (($entry = readdir($handle)) !== false) {
|
|
||||||
if ($this->isHidden($entry)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$this->handle($test, $path . DIRECTORY_SEPARATOR . $entry);
|
|
||||||
}
|
|
||||||
closedir($handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method determines what should be done with a given file and adds
|
|
||||||
* it via {@link GroupTest::addTestFile()} if necessary.
|
|
||||||
*
|
|
||||||
* This method should be overriden to provide custom matching criteria,
|
|
||||||
* such as pattern matching, recursive matching, etc. For an example, see
|
|
||||||
* {@link SimplePatternCollector::_handle()}.
|
|
||||||
*
|
|
||||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
|
||||||
* @param string $filename A filename as generated by {@link collect()}
|
|
||||||
* @see collect()
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected function handle(&$test, $file) {
|
|
||||||
if (is_dir($file)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$test->addFile($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for hidden files so as to skip them. Currently
|
|
||||||
* only tests for Unix hidden files.
|
|
||||||
* @param string $filename Plain filename.
|
|
||||||
* @return boolean True if hidden file.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function isHidden($filename) {
|
|
||||||
return strncmp($filename, '.', 1) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An extension to {@link SimpleCollector} that only adds files matching a
|
|
||||||
* given pattern.
|
|
||||||
*
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
* @see SimpleCollector
|
|
||||||
*/
|
|
||||||
class SimplePatternCollector extends SimpleCollector {
|
|
||||||
private $pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param string $pattern Perl compatible regex to test name against
|
|
||||||
* See {@link http://us4.php.net/manual/en/reference.pcre.pattern.syntax.php PHP's PCRE}
|
|
||||||
* for full documentation of valid pattern.s
|
|
||||||
*/
|
|
||||||
function __construct($pattern = '/php$/i') {
|
|
||||||
$this->pattern = $pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to add files that match a given pattern.
|
|
||||||
*
|
|
||||||
* @see SimpleCollector::_handle()
|
|
||||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
|
||||||
* @param string $path Directory to scan.
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected function handle(&$test, $filename) {
|
|
||||||
if (preg_match($this->pattern, $filename)) {
|
|
||||||
parent::handle($test, $filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,166 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* base include file for SimpleTest
|
|
||||||
* @package SimpleTest
|
|
||||||
* @version $Id: compatibility.php 1900 2009-07-29 11:44:37Z lastcraft $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static methods for compatibility between different
|
|
||||||
* PHP versions.
|
|
||||||
* @package SimpleTest
|
|
||||||
*/
|
|
||||||
class SimpleTestCompatibility {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a copy whether in PHP5 or PHP4.
|
|
||||||
* @param object $object Thing to copy.
|
|
||||||
* @return object A copy.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
static function copy($object) {
|
|
||||||
if (version_compare(phpversion(), '5') >= 0) {
|
|
||||||
eval('$copy = clone $object;');
|
|
||||||
return $copy;
|
|
||||||
}
|
|
||||||
return $object;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Identity test. Drops back to equality + types for PHP5
|
|
||||||
* objects as the === operator counts as the
|
|
||||||
* stronger reference constraint.
|
|
||||||
* @param mixed $first Test subject.
|
|
||||||
* @param mixed $second Comparison object.
|
|
||||||
* @return boolean True if identical.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
static function isIdentical($first, $second) {
|
|
||||||
if (version_compare(phpversion(), '5') >= 0) {
|
|
||||||
return SimpleTestCompatibility::isIdenticalType($first, $second);
|
|
||||||
}
|
|
||||||
if ($first != $second) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ($first === $second);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive type test.
|
|
||||||
* @param mixed $first Test subject.
|
|
||||||
* @param mixed $second Comparison object.
|
|
||||||
* @return boolean True if same type.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected static function isIdenticalType($first, $second) {
|
|
||||||
if (gettype($first) != gettype($second)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (is_object($first) && is_object($second)) {
|
|
||||||
if (get_class($first) != get_class($second)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return SimpleTestCompatibility::isArrayOfIdenticalTypes(
|
|
||||||
(array) $first,
|
|
||||||
(array) $second);
|
|
||||||
}
|
|
||||||
if (is_array($first) && is_array($second)) {
|
|
||||||
return SimpleTestCompatibility::isArrayOfIdenticalTypes($first, $second);
|
|
||||||
}
|
|
||||||
if ($first !== $second) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive type test for each element of an array.
|
|
||||||
* @param mixed $first Test subject.
|
|
||||||
* @param mixed $second Comparison object.
|
|
||||||
* @return boolean True if identical.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected static function isArrayOfIdenticalTypes($first, $second) {
|
|
||||||
if (array_keys($first) != array_keys($second)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
foreach (array_keys($first) as $key) {
|
|
||||||
$is_identical = SimpleTestCompatibility::isIdenticalType(
|
|
||||||
$first[$key],
|
|
||||||
$second[$key]);
|
|
||||||
if (! $is_identical) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for two variables being aliases.
|
|
||||||
* @param mixed $first Test subject.
|
|
||||||
* @param mixed $second Comparison object.
|
|
||||||
* @return boolean True if same.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
static function isReference(&$first, &$second) {
|
|
||||||
if (version_compare(phpversion(), '5', '>=') && is_object($first)) {
|
|
||||||
return ($first === $second);
|
|
||||||
}
|
|
||||||
if (is_object($first) && is_object($second)) {
|
|
||||||
$id = uniqid("test");
|
|
||||||
$first->$id = true;
|
|
||||||
$is_ref = isset($second->$id);
|
|
||||||
unset($first->$id);
|
|
||||||
return $is_ref;
|
|
||||||
}
|
|
||||||
$temp = $first;
|
|
||||||
$first = uniqid("test");
|
|
||||||
$is_ref = ($first === $second);
|
|
||||||
$first = $temp;
|
|
||||||
return $is_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test to see if an object is a member of a
|
|
||||||
* class hiearchy.
|
|
||||||
* @param object $object Object to test.
|
|
||||||
* @param string $class Root name of hiearchy.
|
|
||||||
* @return boolean True if class in hiearchy.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
static function isA($object, $class) {
|
|
||||||
if (version_compare(phpversion(), '5') >= 0) {
|
|
||||||
if (! class_exists($class, false)) {
|
|
||||||
if (function_exists('interface_exists')) {
|
|
||||||
if (! interface_exists($class, false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eval("\$is_a = \$object instanceof $class;");
|
|
||||||
return $is_a;
|
|
||||||
}
|
|
||||||
if (function_exists('is_a')) {
|
|
||||||
return is_a($object, $class);
|
|
||||||
}
|
|
||||||
return ((strtolower($class) == get_class($object))
|
|
||||||
or (is_subclass_of($object, $class)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a socket timeout for each chunk.
|
|
||||||
* @param resource $handle Socket handle.
|
|
||||||
* @param integer $timeout Limit in seconds.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
static function setTimeout($handle, $timeout) {
|
|
||||||
if (function_exists('stream_set_timeout')) {
|
|
||||||
stream_set_timeout($handle, $timeout, 0);
|
|
||||||
} elseif (function_exists('socket_set_timeout')) {
|
|
||||||
socket_set_timeout($handle, $timeout, 0);
|
|
||||||
} elseif (function_exists('set_socket_timeout')) {
|
|
||||||
set_socket_timeout($handle, $timeout, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,380 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Base include file for SimpleTest
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage WebTester
|
|
||||||
* @version $Id: cookies.php 2011 2011-04-29 08:22:48Z pp11 $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* include other SimpleTest class files
|
|
||||||
*/
|
|
||||||
require_once(dirname(__FILE__) . '/url.php');
|
|
||||||
/**#@-*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cookie data holder. Cookie rules are full of pretty
|
|
||||||
* arbitary stuff. I have used...
|
|
||||||
* http://wp.netscape.com/newsref/std/cookie_spec.html
|
|
||||||
* http://www.cookiecentral.com/faq/
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage WebTester
|
|
||||||
*/
|
|
||||||
class SimpleCookie {
|
|
||||||
private $host;
|
|
||||||
private $name;
|
|
||||||
private $value;
|
|
||||||
private $path;
|
|
||||||
private $expiry;
|
|
||||||
private $is_secure;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor. Sets the stored values.
|
|
||||||
* @param string $name Cookie key.
|
|
||||||
* @param string $value Value of cookie.
|
|
||||||
* @param string $path Cookie path if not host wide.
|
|
||||||
* @param string $expiry Expiry date as string.
|
|
||||||
* @param boolean $is_secure Currently ignored.
|
|
||||||
*/
|
|
||||||
function __construct($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
|
|
||||||
$this->host = false;
|
|
||||||
$this->name = $name;
|
|
||||||
$this->value = $value;
|
|
||||||
$this->path = ($path ? $this->fixPath($path) : "/");
|
|
||||||
$this->expiry = false;
|
|
||||||
if (is_string($expiry)) {
|
|
||||||
$this->expiry = strtotime($expiry);
|
|
||||||
} elseif (is_integer($expiry)) {
|
|
||||||
$this->expiry = $expiry;
|
|
||||||
}
|
|
||||||
$this->is_secure = $is_secure;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the host. The cookie rules determine
|
|
||||||
* that the first two parts are taken for
|
|
||||||
* certain TLDs and three for others. If the
|
|
||||||
* new host does not match these rules then the
|
|
||||||
* call will fail.
|
|
||||||
* @param string $host New hostname.
|
|
||||||
* @return boolean True if hostname is valid.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function setHost($host) {
|
|
||||||
if ($host = $this->truncateHost($host)) {
|
|
||||||
$this->host = $host;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for the truncated host to which this
|
|
||||||
* cookie applies.
|
|
||||||
* @return string Truncated hostname.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getHost() {
|
|
||||||
return $this->host;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for a cookie being valid for a host name.
|
|
||||||
* @param string $host Host to test against.
|
|
||||||
* @return boolean True if the cookie would be valid
|
|
||||||
* here.
|
|
||||||
*/
|
|
||||||
function isValidHost($host) {
|
|
||||||
return ($this->truncateHost($host) === $this->getHost());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts just the domain part that determines a
|
|
||||||
* cookie's host validity.
|
|
||||||
* @param string $host Host name to truncate.
|
|
||||||
* @return string Domain or false on a bad host.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function truncateHost($host) {
|
|
||||||
$tlds = SimpleUrl::getAllTopLevelDomains();
|
|
||||||
if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
|
|
||||||
return $matches[0];
|
|
||||||
} elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
|
|
||||||
return $matches[0];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for name.
|
|
||||||
* @return string Cookie key.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getName() {
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for value. A deleted cookie will
|
|
||||||
* have an empty string for this.
|
|
||||||
* @return string Cookie value.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getValue() {
|
|
||||||
return $this->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for path.
|
|
||||||
* @return string Valid cookie path.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getPath() {
|
|
||||||
return $this->path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests a path to see if the cookie applies
|
|
||||||
* there. The test path must be longer or
|
|
||||||
* equal to the cookie path.
|
|
||||||
* @param string $path Path to test against.
|
|
||||||
* @return boolean True if cookie valid here.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function isValidPath($path) {
|
|
||||||
return (strncmp(
|
|
||||||
$this->fixPath($path),
|
|
||||||
$this->getPath(),
|
|
||||||
strlen($this->getPath())) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for expiry.
|
|
||||||
* @return string Expiry string.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getExpiry() {
|
|
||||||
if (! $this->expiry) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return gmdate("D, d M Y H:i:s", $this->expiry) . " GMT";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test to see if cookie is expired against
|
|
||||||
* the cookie format time or timestamp.
|
|
||||||
* Will give true for a session cookie.
|
|
||||||
* @param integer/string $now Time to test against. Result
|
|
||||||
* will be false if this time
|
|
||||||
* is later than the cookie expiry.
|
|
||||||
* Can be either a timestamp integer
|
|
||||||
* or a cookie format date.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function isExpired($now) {
|
|
||||||
if (! $this->expiry) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (is_string($now)) {
|
|
||||||
$now = strtotime($now);
|
|
||||||
}
|
|
||||||
return ($this->expiry < $now);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ages the cookie by the specified number of
|
|
||||||
* seconds.
|
|
||||||
* @param integer $interval In seconds.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
function agePrematurely($interval) {
|
|
||||||
if ($this->expiry) {
|
|
||||||
$this->expiry -= $interval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for the secure flag.
|
|
||||||
* @return boolean True if cookie needs SSL.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function isSecure() {
|
|
||||||
return $this->is_secure;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a trailing and leading slash to the path
|
|
||||||
* if missing.
|
|
||||||
* @param string $path Path to fix.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function fixPath($path) {
|
|
||||||
if (substr($path, 0, 1) != '/') {
|
|
||||||
$path = '/' . $path;
|
|
||||||
}
|
|
||||||
if (substr($path, -1, 1) != '/') {
|
|
||||||
$path .= '/';
|
|
||||||
}
|
|
||||||
return $path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository for cookies. This stuff is a
|
|
||||||
* tiny bit browser dependent.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage WebTester
|
|
||||||
*/
|
|
||||||
class SimpleCookieJar {
|
|
||||||
private $cookies;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor. Jar starts empty.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function __construct() {
|
|
||||||
$this->cookies = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes expired and temporary cookies as if
|
|
||||||
* the browser was closed and re-opened.
|
|
||||||
* @param string/integer $now Time to test expiry against.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function restartSession($date = false) {
|
|
||||||
$surviving_cookies = array();
|
|
||||||
for ($i = 0; $i < count($this->cookies); $i++) {
|
|
||||||
if (! $this->cookies[$i]->getValue()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (! $this->cookies[$i]->getExpiry()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($date && $this->cookies[$i]->isExpired($date)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$surviving_cookies[] = $this->cookies[$i];
|
|
||||||
}
|
|
||||||
$this->cookies = $surviving_cookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ages all cookies in the cookie jar.
|
|
||||||
* @param integer $interval The old session is moved
|
|
||||||
* into the past by this number
|
|
||||||
* of seconds. Cookies now over
|
|
||||||
* age will be removed.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function agePrematurely($interval) {
|
|
||||||
for ($i = 0; $i < count($this->cookies); $i++) {
|
|
||||||
$this->cookies[$i]->agePrematurely($interval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets an additional cookie. If a cookie has
|
|
||||||
* the same name and path it is replaced.
|
|
||||||
* @param string $name Cookie key.
|
|
||||||
* @param string $value Value of cookie.
|
|
||||||
* @param string $host Host upon which the cookie is valid.
|
|
||||||
* @param string $path Cookie path if not host wide.
|
|
||||||
* @param string $expiry Expiry date.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
|
||||||
$cookie = new SimpleCookie($name, $value, $path, $expiry);
|
|
||||||
if ($host) {
|
|
||||||
$cookie->setHost($host);
|
|
||||||
}
|
|
||||||
$this->cookies[$this->findFirstMatch($cookie)] = $cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a matching cookie to write over or the
|
|
||||||
* first empty slot if none.
|
|
||||||
* @param SimpleCookie $cookie Cookie to write into jar.
|
|
||||||
* @return integer Available slot.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function findFirstMatch($cookie) {
|
|
||||||
for ($i = 0; $i < count($this->cookies); $i++) {
|
|
||||||
$is_match = $this->isMatch(
|
|
||||||
$cookie,
|
|
||||||
$this->cookies[$i]->getHost(),
|
|
||||||
$this->cookies[$i]->getPath(),
|
|
||||||
$this->cookies[$i]->getName());
|
|
||||||
if ($is_match) {
|
|
||||||
return $i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count($this->cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the most specific cookie value from the
|
|
||||||
* browser cookies. Looks for the longest path that
|
|
||||||
* matches.
|
|
||||||
* @param string $host Host to search.
|
|
||||||
* @param string $path Applicable path.
|
|
||||||
* @param string $name Name of cookie to read.
|
|
||||||
* @return string False if not present, else the
|
|
||||||
* value as a string.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getCookieValue($host, $path, $name) {
|
|
||||||
$longest_path = '';
|
|
||||||
foreach ($this->cookies as $cookie) {
|
|
||||||
if ($this->isMatch($cookie, $host, $path, $name)) {
|
|
||||||
if (strlen($cookie->getPath()) > strlen($longest_path)) {
|
|
||||||
$value = $cookie->getValue();
|
|
||||||
$longest_path = $cookie->getPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (isset($value) ? $value : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests cookie for matching against search
|
|
||||||
* criteria.
|
|
||||||
* @param SimpleTest $cookie Cookie to test.
|
|
||||||
* @param string $host Host must match.
|
|
||||||
* @param string $path Cookie path must be shorter than
|
|
||||||
* this path.
|
|
||||||
* @param string $name Name must match.
|
|
||||||
* @return boolean True if matched.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
protected function isMatch($cookie, $host, $path, $name) {
|
|
||||||
if ($cookie->getName() != $name) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (! $cookie->isValidPath($path)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses a URL to sift relevant cookies by host and
|
|
||||||
* path. Results are list of strings of form "name=value".
|
|
||||||
* @param SimpleUrl $url Url to select by.
|
|
||||||
* @return array Valid name and value pairs.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function selectAsPairs($url) {
|
|
||||||
$pairs = array();
|
|
||||||
foreach ($this->cookies as $cookie) {
|
|
||||||
if ($this->isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
|
|
||||||
$pairs[] = $cookie->getName() . '=' . $cookie->getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $pairs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,163 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Optional include file for SimpleTest
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
* @version $Id: default_reporter.php 2011 2011-04-29 08:22:48Z pp11 $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* include other SimpleTest class files
|
|
||||||
*/
|
|
||||||
require_once(dirname(__FILE__) . '/simpletest.php');
|
|
||||||
require_once(dirname(__FILE__) . '/scorer.php');
|
|
||||||
require_once(dirname(__FILE__) . '/reporter.php');
|
|
||||||
require_once(dirname(__FILE__) . '/xml.php');
|
|
||||||
/**#@-*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parser for command line arguments. Extracts
|
|
||||||
* the a specific test to run and engages XML
|
|
||||||
* reporting when necessary.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
*/
|
|
||||||
class SimpleCommandLineParser {
|
|
||||||
private $to_property = array(
|
|
||||||
'case' => 'case', 'c' => 'case',
|
|
||||||
'test' => 'test', 't' => 'test',
|
|
||||||
);
|
|
||||||
private $case = '';
|
|
||||||
private $test = '';
|
|
||||||
private $xml = false;
|
|
||||||
private $help = false;
|
|
||||||
private $no_skips = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses raw command line arguments into object properties.
|
|
||||||
* @param string $arguments Raw commend line arguments.
|
|
||||||
*/
|
|
||||||
function __construct($arguments) {
|
|
||||||
if (! is_array($arguments)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach ($arguments as $i => $argument) {
|
|
||||||
if (preg_match('/^--?(test|case|t|c)=(.+)$/', $argument, $matches)) {
|
|
||||||
$property = $this->to_property[$matches[1]];
|
|
||||||
$this->$property = $matches[2];
|
|
||||||
} elseif (preg_match('/^--?(test|case|t|c)$/', $argument, $matches)) {
|
|
||||||
$property = $this->to_property[$matches[1]];
|
|
||||||
if (isset($arguments[$i + 1])) {
|
|
||||||
$this->$property = $arguments[$i + 1];
|
|
||||||
}
|
|
||||||
} elseif (preg_match('/^--?(xml|x)$/', $argument)) {
|
|
||||||
$this->xml = true;
|
|
||||||
} elseif (preg_match('/^--?(no-skip|no-skips|s)$/', $argument)) {
|
|
||||||
$this->no_skips = true;
|
|
||||||
} elseif (preg_match('/^--?(help|h)$/', $argument)) {
|
|
||||||
$this->help = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run only this test.
|
|
||||||
* @return string Test name to run.
|
|
||||||
*/
|
|
||||||
function getTest() {
|
|
||||||
return $this->test;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run only this test suite.
|
|
||||||
* @return string Test class name to run.
|
|
||||||
*/
|
|
||||||
function getTestCase() {
|
|
||||||
return $this->case;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output should be XML or not.
|
|
||||||
* @return boolean True if XML desired.
|
|
||||||
*/
|
|
||||||
function isXml() {
|
|
||||||
return $this->xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output should suppress skip messages.
|
|
||||||
* @return boolean True for no skips.
|
|
||||||
*/
|
|
||||||
function noSkips() {
|
|
||||||
return $this->no_skips;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output should be a help message. Disabled during XML mode.
|
|
||||||
* @return boolean True if help message desired.
|
|
||||||
*/
|
|
||||||
function help() {
|
|
||||||
return $this->help && ! $this->xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns plain-text help message for command line runner.
|
|
||||||
* @return string String help message
|
|
||||||
*/
|
|
||||||
function getHelpText() {
|
|
||||||
return <<<HELP
|
|
||||||
SimpleTest command line default reporter (autorun)
|
|
||||||
Usage: php <test_file> [args...]
|
|
||||||
|
|
||||||
-c <class> Run only the test-case <class>
|
|
||||||
-t <method> Run only the test method <method>
|
|
||||||
-s Suppress skip messages
|
|
||||||
-x Return test results in XML
|
|
||||||
-h Display this help message
|
|
||||||
|
|
||||||
HELP;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default reporter used by SimpleTest's autorun
|
|
||||||
* feature. The actual reporters used are dependency
|
|
||||||
* injected and can be overridden.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
*/
|
|
||||||
class DefaultReporter extends SimpleReporterDecorator {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assembles the appropriate reporter for the environment.
|
|
||||||
*/
|
|
||||||
function __construct() {
|
|
||||||
if (SimpleReporter::inCli()) {
|
|
||||||
$parser = new SimpleCommandLineParser($_SERVER['argv']);
|
|
||||||
$interfaces = $parser->isXml() ? array('XmlReporter') : array('TextReporter');
|
|
||||||
if ($parser->help()) {
|
|
||||||
// I'm not sure if we should do the echo'ing here -- ezyang
|
|
||||||
echo $parser->getHelpText();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
$reporter = new SelectiveReporter(
|
|
||||||
SimpleTest::preferred($interfaces),
|
|
||||||
$parser->getTestCase(),
|
|
||||||
$parser->getTest());
|
|
||||||
if ($parser->noSkips()) {
|
|
||||||
$reporter = new NoSkipsReporter($reporter);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$reporter = new SelectiveReporter(
|
|
||||||
SimpleTest::preferred('HtmlReporter'),
|
|
||||||
@$_GET['c'],
|
|
||||||
@$_GET['t']);
|
|
||||||
if (@$_GET['skips'] == 'no' || @$_GET['show-skips'] == 'no') {
|
|
||||||
$reporter = new NoSkipsReporter($reporter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent::__construct($reporter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,96 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* base include file for SimpleTest
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
* @version $Id: detached.php 1784 2008-04-26 13:07:14Z pp11 $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* include other SimpleTest class files
|
|
||||||
*/
|
|
||||||
require_once(dirname(__FILE__) . '/xml.php');
|
|
||||||
require_once(dirname(__FILE__) . '/shell_tester.php');
|
|
||||||
/**#@-*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs an XML formated test in a separate process.
|
|
||||||
* @package SimpleTest
|
|
||||||
* @subpackage UnitTester
|
|
||||||
*/
|
|
||||||
class DetachedTestCase {
|
|
||||||
private $command;
|
|
||||||
private $dry_command;
|
|
||||||
private $size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the location of the remote test.
|
|
||||||
* @param string $command Test script.
|
|
||||||
* @param string $dry_command Script for dry run.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function __construct($command, $dry_command = false) {
|
|
||||||
$this->command = $command;
|
|
||||||
$this->dry_command = $dry_command ? $dry_command : $command;
|
|
||||||
$this->size = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for the test name for subclasses.
|
|
||||||
* @return string Name of the test.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getLabel() {
|
|
||||||
return $this->command;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the top level test for this class. Currently
|
|
||||||
* reads the data as a single chunk. I'll fix this
|
|
||||||
* once I have added iteration to the browser.
|
|
||||||
* @param SimpleReporter $reporter Target of test results.
|
|
||||||
* @returns boolean True if no failures.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function run(&$reporter) {
|
|
||||||
$shell = &new SimpleShell();
|
|
||||||
$shell->execute($this->command);
|
|
||||||
$parser = &$this->createParser($reporter);
|
|
||||||
if (! $parser->parse($shell->getOutput())) {
|
|
||||||
trigger_error('Cannot parse incoming XML from [' . $this->command . ']');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for the number of subtests.
|
|
||||||
* @return integer Number of test cases.
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function getSize() {
|
|
||||||
if ($this->size === false) {
|
|
||||||
$shell = &new SimpleShell();
|
|
||||||
$shell->execute($this->dry_command);
|
|
||||||
$reporter = &new SimpleReporter();
|
|
||||||
$parser = &$this->createParser($reporter);
|
|
||||||
if (! $parser->parse($shell->getOutput())) {
|
|
||||||
trigger_error('Cannot parse incoming XML from [' . $this->dry_command . ']');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->size = $reporter->getTestCaseCount();
|
|
||||||
}
|
|
||||||
return $this->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the XML parser.
|
|
||||||
* @param SimpleReporter $reporter Target of test results.
|
|
||||||
* @return SimpleTestXmlListener XML reader.
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected function &createParser(&$reporter) {
|
|
||||||
return new SimpleTestXmlParser($reporter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,378 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest documentation for testing log-in and authentication</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Authentication</span>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Authentication documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Getting through <a href="#basic">Basic HTTP authentication</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Testing <a href="#cookies">cookie based authentication</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Managing <a href="#session">browser sessions</a> and timeouts
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
One of the trickiest, and yet most important, areas
|
|
||||||
of testing web sites is the security.
|
|
||||||
Testing these schemes is one of the core goals of
|
|
||||||
the SimpleTest web tester.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="basic"></a>Basic HTTP authentication</h2>
|
|
||||||
<p>
|
|
||||||
If you fetch a page protected by basic authentication then
|
|
||||||
rather than receiving content, you will instead get a 401
|
|
||||||
header.
|
|
||||||
We can illustrate this with this test...
|
|
||||||
<pre>
|
|
||||||
class AuthenticationTest extends WebTestCase {<strong>
|
|
||||||
function test401Header() {
|
|
||||||
$this->get('http://www.lastcraft.com/protected/');
|
|
||||||
$this->showHeaders();
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This allows us to see the challenge header...
|
|
||||||
<div class="demo">
|
|
||||||
<h1>File test</h1>
|
|
||||||
<pre>
|
|
||||||
HTTP/1.1 401 Authorization Required
|
|
||||||
Date: Sat, 18 Sep 2004 19:25:18 GMT
|
|
||||||
Server: Apache/1.3.29 (Unix) PHP/4.3.4
|
|
||||||
WWW-Authenticate: Basic realm="SimpleTest basic authentication"
|
|
||||||
Connection: close
|
|
||||||
Content-Type: text/html; charset=iso-8859-1
|
|
||||||
</pre>
|
|
||||||
<div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
|
|
||||||
<strong>0</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
|
|
||||||
</div>
|
|
||||||
We are trying to get away from visual inspection though, and so SimpleTest
|
|
||||||
allows to make automated assertions against the challenge.
|
|
||||||
Here is a thorough test of our header...
|
|
||||||
<pre>
|
|
||||||
class AuthenticationTest extends WebTestCase {
|
|
||||||
function test401Header() {
|
|
||||||
$this->get('http://www.lastcraft.com/protected/');<strong>
|
|
||||||
$this->assertAuthentication('Basic');
|
|
||||||
$this->assertResponse(401);
|
|
||||||
$this->assertRealm('SimpleTest basic authentication');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Any one of these tests would normally do on it's own depending
|
|
||||||
on the amount of detail you want to see.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
One theme that runs through SimpleTest is the ability to use
|
|
||||||
<span class="new_code">SimpleExpectation</span> objects wherever a simple
|
|
||||||
match is not enough.
|
|
||||||
If you want only an approximate match to the realm for
|
|
||||||
example, you can do this...
|
|
||||||
<pre>
|
|
||||||
class AuthenticationTest extends WebTestCase {
|
|
||||||
function test401Header() {
|
|
||||||
$this->get('http://www.lastcraft.com/protected/');
|
|
||||||
$this->assertRealm(<strong>new PatternExpectation('/simpletest/i')</strong>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This type of test, testing HTTP responses, is not typical.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Most of the time we are not interested in testing the
|
|
||||||
authentication itself, but want to get past it to test
|
|
||||||
the pages underneath.
|
|
||||||
As soon as the challenge has been issued we can reply with
|
|
||||||
an authentication response...
|
|
||||||
<pre>
|
|
||||||
class AuthenticationTest extends WebTestCase {
|
|
||||||
function testCanAuthenticate() {
|
|
||||||
$this->get('http://www.lastcraft.com/protected/');<strong>
|
|
||||||
$this->authenticate('Me', 'Secret');</strong>
|
|
||||||
$this->assertTitle(...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The username and password will now be sent with every
|
|
||||||
subsequent request to that directory and subdirectories.
|
|
||||||
You will have to authenticate again if you step outside
|
|
||||||
the authenticated directory, but SimpleTest is smart enough
|
|
||||||
to merge subdirectories into a common realm.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you want, you can shortcut this step further by encoding
|
|
||||||
the log in details straight into the URL...
|
|
||||||
<pre>
|
|
||||||
class AuthenticationTest extends WebTestCase {
|
|
||||||
function testCanReadAuthenticatedPages() {
|
|
||||||
$this->get('http://<strong>Me:Secret@</strong>www.lastcraft.com/protected/');
|
|
||||||
$this->assertTitle(...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
If your username or password has special characters, then you
|
|
||||||
will have to URL encode them or the request will not be parsed
|
|
||||||
correctly.
|
|
||||||
I'm afraid we leave this up to you.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A problem with encoding the login details directly in the URL is
|
|
||||||
the authentication header will not be sent on subsequent requests.
|
|
||||||
If you navigate with relative URLs though, the authentication
|
|
||||||
information will be preserved along with the domain name.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Normally though, you use the <span class="new_code">authenticate()</span> call.
|
|
||||||
SimpleTest will then remember your login information on each request.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Only testing with basic authentication is currently supported, and
|
|
||||||
this is only really secure in tandem with HTTPS connections.
|
|
||||||
This is usually good enough to protect test server from prying eyes,
|
|
||||||
however.
|
|
||||||
Digest authentication and NTLM authentication may be added
|
|
||||||
in the future if enough people request this feature.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="cookies"></a>Cookies</h2>
|
|
||||||
<p>
|
|
||||||
Basic authentication doesn't give enough control over the
|
|
||||||
user interface for web developers.
|
|
||||||
More likely this functionality will be coded directly into
|
|
||||||
the web architecture using cookies with complicated timeouts.
|
|
||||||
We need to be able to test this too.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Starting with a simple log-in form...
|
|
||||||
<pre>
|
|
||||||
<form>
|
|
||||||
Username:
|
|
||||||
<input type="text" name="u" value="" /><br />
|
|
||||||
Password:
|
|
||||||
<input type="password" name="p" value="" /><br />
|
|
||||||
<input type="submit" value="Log in" />
|
|
||||||
</form>
|
|
||||||
</pre>
|
|
||||||
Which looks like...
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<form class="demo">
|
|
||||||
Username:
|
|
||||||
<input type="text" name="u" value=""><br>
|
|
||||||
Password:
|
|
||||||
<input type="password" name="p" value=""><br>
|
|
||||||
<input type="submit" value="Log in">
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Let's suppose that in fetching this page a cookie has been
|
|
||||||
set with a session ID.
|
|
||||||
We are not going to fill the form in yet, just test that
|
|
||||||
we are tracking the user.
|
|
||||||
Here is the test...
|
|
||||||
<pre>
|
|
||||||
class LogInTest extends WebTestCase {
|
|
||||||
function testSessionCookieSetBeforeForm() {
|
|
||||||
$this->get('http://www.my-site.com/login.php');<strong>
|
|
||||||
$this->assertCookie('SID');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
All we are doing is confirming that the cookie is set.
|
|
||||||
As the value is likely to be rather cryptic it's not
|
|
||||||
really worth testing this with...
|
|
||||||
<pre>
|
|
||||||
class LogInTest extends WebTestCase {
|
|
||||||
function testSessionCookieIsCorrectPattern() {
|
|
||||||
$this->get('http://www.my-site.com/login.php');
|
|
||||||
$this->assertCookie('SID', <strong>new PatternExpectation('/[a-f0-9]{32}/i')</strong>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
If you are using PHP to handle sessions for you then
|
|
||||||
this test is even more useless, as we are just testing PHP itself.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The simplest test of logging in is to visually inspect the
|
|
||||||
next page to see if you are really logged in.
|
|
||||||
Just test the next page with <span class="new_code">WebTestCase::assertText()</span>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The test is similar to any other form test,
|
|
||||||
but we might want to confirm that we still have the same
|
|
||||||
cookie after log-in as before we entered.
|
|
||||||
We wouldn't want to lose track of this after all.
|
|
||||||
Here is a possible test for this...
|
|
||||||
<pre>
|
|
||||||
class LogInTest extends WebTestCase {
|
|
||||||
...
|
|
||||||
function testSessionCookieSameAfterLogIn() {
|
|
||||||
$this->get('http://www.my-site.com/login.php');<strong>
|
|
||||||
$session = $this->getCookie('SID');
|
|
||||||
$this->setField('u', 'Me');
|
|
||||||
$this->setField('p', 'Secret');
|
|
||||||
$this->click('Log in');
|
|
||||||
$this->assertText('Welcome Me');
|
|
||||||
$this->assertCookie('SID', $session);</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This confirms that the session identifier is maintained
|
|
||||||
afer log-in and we haven't accidently reset it.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We could even attempt to hack our own system by setting
|
|
||||||
arbitrary cookies to gain access...
|
|
||||||
<pre>
|
|
||||||
class LogInTest extends WebTestCase {
|
|
||||||
...
|
|
||||||
function testSessionCookieSameAfterLogIn() {
|
|
||||||
$this->get('http://www.my-site.com/login.php');<strong>
|
|
||||||
$this->setCookie('SID', 'Some other session');
|
|
||||||
$this->get('http://www.my-site.com/restricted.php');</strong>
|
|
||||||
$this->assertText('Access denied');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Is your site protected from this attack?
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="session"></a>Browser sessions</h2>
|
|
||||||
<p>
|
|
||||||
If you are testing an authentication system a critical piece
|
|
||||||
of behaviour is what happens when a user logs back in.
|
|
||||||
We would like to simulate closing and reopening a browser...
|
|
||||||
<pre>
|
|
||||||
class LogInTest extends WebTestCase {
|
|
||||||
...
|
|
||||||
function testLoseAuthenticationAfterBrowserClose() {
|
|
||||||
$this->get('http://www.my-site.com/login.php');
|
|
||||||
$this->setField('u', 'Me');
|
|
||||||
$this->setField('p', 'Secret');
|
|
||||||
$this->click('Log in');
|
|
||||||
$this->assertText('Welcome Me');<strong>
|
|
||||||
|
|
||||||
$this->restart();
|
|
||||||
$this->get('http://www.my-site.com/restricted.php');
|
|
||||||
$this->assertText('Access denied');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The <span class="new_code">WebTestCase::restart()</span> method will
|
|
||||||
preserve cookies that have unexpired timeouts, but throw away
|
|
||||||
those that are temporary or expired.
|
|
||||||
You can optionally specify the time and date that the restart
|
|
||||||
happened.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Expiring cookies can be a problem.
|
|
||||||
After all, if you have a cookie that expires after an hour,
|
|
||||||
you don't want to stall the test for an hour while waiting
|
|
||||||
for the cookie to pass it's timeout.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To push the cookies over the hour limit you can age them
|
|
||||||
before you restart the session...
|
|
||||||
<pre>
|
|
||||||
class LogInTest extends WebTestCase {
|
|
||||||
...
|
|
||||||
function testLoseAuthenticationAfterOneHour() {
|
|
||||||
$this->get('http://www.my-site.com/login.php');
|
|
||||||
$this->setField('u', 'Me');
|
|
||||||
$this->setField('p', 'Secret');
|
|
||||||
$this->click('Log in');
|
|
||||||
$this->assertText('Welcome Me');
|
|
||||||
<strong>
|
|
||||||
$this->ageCookies(3600);</strong>
|
|
||||||
$this->restart();
|
|
||||||
$this->get('http://www.my-site.com/restricted.php');
|
|
||||||
$this->assertText('Access denied');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
After the restart it will appear that cookies are an
|
|
||||||
hour older, and any that pass their expiry will have
|
|
||||||
disappeared.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
|
|
||||||
gives full detail on the classes and assertions available.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Authentication</span>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,501 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest documentation for the scriptable web browser component</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Scriptable browser</span>
|
|
||||||
</div></div>
|
|
||||||
<h1>PHP Scriptable Web Browser</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Using the bundled <a href="#scripting">web browser in scripts</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#debug">Debugging</a> failed pages
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Complex <a href="#unit">tests with multiple web browsers</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
SimpleTest's web browser component can be used not just
|
|
||||||
outside of the <span class="new_code">WebTestCase</span> class, but also
|
|
||||||
independently of the SimpleTest framework itself.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="scripting"></a>The Scriptable Browser</h2>
|
|
||||||
<p>
|
|
||||||
You can use the web browser in PHP scripts to confirm
|
|
||||||
services are up and running, or to extract information
|
|
||||||
from them at a regular basis.
|
|
||||||
For example, here is a small script to extract the current number of
|
|
||||||
open PHP 5 bugs from the <a href="http://www.php.net/">PHP web site</a>...
|
|
||||||
<pre>
|
|
||||||
<strong><?php
|
|
||||||
require_once('simpletest/browser.php');
|
|
||||||
|
|
||||||
$browser = &new SimpleBrowser();
|
|
||||||
$browser->get('http://php.net/');
|
|
||||||
$browser->click('reporting bugs');
|
|
||||||
$browser->click('statistics');
|
|
||||||
$page = $browser->click('PHP 5 bugs only');
|
|
||||||
preg_match('/status=Open.*?by=Any.*?(\d+)<\/a>/', $page, $matches);
|
|
||||||
print $matches[1];
|
|
||||||
?></strong>
|
|
||||||
</pre>
|
|
||||||
There are simpler methods to do this particular example in PHP
|
|
||||||
of course.
|
|
||||||
For example you can just use the PHP <span class="new_code">file()</span>
|
|
||||||
command against what here is a pretty fixed page.
|
|
||||||
However, using the web browser for scripts allows authentication,
|
|
||||||
correct handling of cookies, automatic loading of frames, redirects,
|
|
||||||
form submission and the ability to examine the page headers.
|
|
||||||
<p>
|
|
||||||
</p>
|
|
||||||
Methods such as periodic scraping are fragile against a site that is constantly
|
|
||||||
evolving and you would want a more direct way of accessing
|
|
||||||
data in a permanent set up, but for simple tasks this can provide
|
|
||||||
a very rapid solution.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
All of the navigation methods used in the
|
|
||||||
<a href="web_tester_documentation.html">WebTestCase</a>
|
|
||||||
are present in the <span class="new_code">SimpleBrowser</span> class, but
|
|
||||||
the assertions are replaced with simpler accessors.
|
|
||||||
Here is a full list of the page navigation methods...
|
|
||||||
<table><tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">addHeader($header)</span></td>
|
|
||||||
<td>Adds a header to every fetch</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">useProxy($proxy, $username, $password)</span></td>
|
|
||||||
<td>Use this proxy from now on</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">head($url, $parameters)</span></td>
|
|
||||||
<td>Perform a HEAD request</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">get($url, $parameters)</span></td>
|
|
||||||
<td>Fetch a page with GET</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">post($url, $parameters)</span></td>
|
|
||||||
<td>Fetch a page with POST</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">click($label)</span></td>
|
|
||||||
<td>Clicks visible link or button text</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickLink($label)</span></td>
|
|
||||||
<td>Follows a link by label</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickLinkById($id)</span></td>
|
|
||||||
<td>Follows a link by attribute</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getUrl()</span></td>
|
|
||||||
<td>Current URL of page or frame</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getTitle()</span></td>
|
|
||||||
<td>Page title</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getContent()</span></td>
|
|
||||||
<td>Raw page or frame</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getContentAsText()</span></td>
|
|
||||||
<td>HTML removed except for alt text</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">retry()</span></td>
|
|
||||||
<td>Repeat the last request</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">back()</span></td>
|
|
||||||
<td>Use the browser back button</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">forward()</span></td>
|
|
||||||
<td>Use the browser forward button</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">authenticate($username, $password)</span></td>
|
|
||||||
<td>Retry page or frame after a 401 response</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">restart($date)</span></td>
|
|
||||||
<td>Restarts the browser for a new session</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">ageCookies($interval)</span></td>
|
|
||||||
<td>Ages the cookies by the specified time</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setCookie($name, $value)</span></td>
|
|
||||||
<td>Sets an additional cookie</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getCookieValue($host, $path, $name)</span></td>
|
|
||||||
<td>Reads the most specific cookie</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getCurrentCookieValue($name)</span></td>
|
|
||||||
<td>Reads cookie for the current context</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
The methods <span class="new_code">SimpleBrowser::useProxy()</span> and
|
|
||||||
<span class="new_code">SimpleBrowser::addHeader()</span> are special.
|
|
||||||
Once called they continue to apply to all subsequent fetches.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Navigating forms is similar to the
|
|
||||||
<a href="form_testing_documentation.html">WebTestCase form navigation</a>...
|
|
||||||
<table><tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setField($label, $value)</span></td>
|
|
||||||
<td>Sets all form fields with that label or name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setFieldByName($name, $value)</span></td>
|
|
||||||
<td>Sets all form fields with that name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setFieldById($id, $value)</span></td>
|
|
||||||
<td>Sets all form fields with that id</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getField($label)</span></td>
|
|
||||||
<td>Accessor for a form element value by label tag and then name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getFieldByName($name)</span></td>
|
|
||||||
<td>Accessor for a form element value using name attribute</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getFieldById($id)</span></td>
|
|
||||||
<td>Accessor for a form element value</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickSubmit($label)</span></td>
|
|
||||||
<td>Submits form by button label</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickSubmitByName($name)</span></td>
|
|
||||||
<td>Submits form by button attribute</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickSubmitById($id)</span></td>
|
|
||||||
<td>Submits form by button attribute</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickImage($label, $x, $y)</span></td>
|
|
||||||
<td>Clicks an input tag of type image by title or alt text</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
|
|
||||||
<td>Clicks an input tag of type image by name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clickImageById($id, $x, $y)</span></td>
|
|
||||||
<td>Clicks an input tag of type image by ID attribute</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">submitFormById($id)</span></td>
|
|
||||||
<td>Submits by the form tag attribute</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
At the moment there aren't many methods to list available links and fields.
|
|
||||||
<table><tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">isClickable($label)</span></td>
|
|
||||||
<td>Test to see if a click target exists by label or name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">isSubmit($label)</span></td>
|
|
||||||
<td>Test for the existence of a button with that label or name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">isImage($label)</span></td>
|
|
||||||
<td>Test for the existence of an image button with that label or name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getLink($label)</span></td>
|
|
||||||
<td>Finds a URL from its label</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getLinkById($label)</span></td>
|
|
||||||
<td>Finds a URL from its ID attribute</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getUrls()</span></td>
|
|
||||||
<td>Lists available links in the current page</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
This will be expanded in later versions of SimpleTest.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Frames are a rather esoteric feature these days, but SimpleTest has
|
|
||||||
retained support for them.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Within a page, individual frames can be selected.
|
|
||||||
If no selection is made then all the frames are merged together
|
|
||||||
in one large conceptual page.
|
|
||||||
The content of the current page will be a concatenation of all of the
|
|
||||||
frames in the order that they were specified in the "frameset"
|
|
||||||
tags.
|
|
||||||
<table><tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getFrames()</span></td>
|
|
||||||
<td>A dump of the current frame structure</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getFrameFocus()</span></td>
|
|
||||||
<td>Current frame label or index</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
|
|
||||||
<td>Select a frame numbered from 1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setFrameFocus($name)</span></td>
|
|
||||||
<td>Select frame by label</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">clearFrameFocus()</span></td>
|
|
||||||
<td>Treat all the frames as a single page</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
When focused on a single frame, the content will come from
|
|
||||||
that frame only.
|
|
||||||
This includes links to click and forms to submit.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="debug"></a>What went wrong?</h2>
|
|
||||||
<p>
|
|
||||||
All of this functionality is great when we actually manage to fetch pages,
|
|
||||||
but that doesn't always happen.
|
|
||||||
To help figure out what went wrong, the browser has some methods to
|
|
||||||
aid in debugging...
|
|
||||||
<table><tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setConnectionTimeout($timeout)</span></td>
|
|
||||||
<td>Close the socket on overrun</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getUrl()</span></td>
|
|
||||||
<td>Url of most recent page fetched</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getRequest()</span></td>
|
|
||||||
<td>Raw request header of page or frame</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getHeaders()</span></td>
|
|
||||||
<td>Raw response header of page or frame</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getTransportError()</span></td>
|
|
||||||
<td>Any socket level errors in the last fetch</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getResponseCode()</span></td>
|
|
||||||
<td>HTTP response of page or frame</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getMimeType()</span></td>
|
|
||||||
<td>Mime type of page or frame</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getAuthentication()</span></td>
|
|
||||||
<td>Authentication type in 401 challenge header</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getRealm()</span></td>
|
|
||||||
<td>Authentication realm in 401 challenge header</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">getBaseUrl()</span></td>
|
|
||||||
<td>Base url only of most recent page fetched</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setMaximumRedirects($max)</span></td>
|
|
||||||
<td>Number of redirects before page is loaded anyway</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">setMaximumNestedFrames($max)</span></td>
|
|
||||||
<td>Protection against recursive framesets</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">ignoreFrames()</span></td>
|
|
||||||
<td>Disables frames support</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">useFrames()</span></td>
|
|
||||||
<td>Enables frames support</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">ignoreCookies()</span></td>
|
|
||||||
<td>Disables sending and receiving of cookies</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">useCookies()</span></td>
|
|
||||||
<td>Enables cookie support</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
The methods <span class="new_code">SimpleBrowser::setConnectionTimeout()</span>
|
|
||||||
<span class="new_code">SimpleBrowser::setMaximumRedirects()</span>,
|
|
||||||
<span class="new_code">SimpleBrowser::setMaximumNestedFrames()</span>,
|
|
||||||
<span class="new_code">SimpleBrowser::ignoreFrames()</span>,
|
|
||||||
<span class="new_code">SimpleBrowser::useFrames()</span>,
|
|
||||||
<span class="new_code">SimpleBrowser::ignoreCookies()</span> and
|
|
||||||
<span class="new_code">SimpleBrowser::useCokies()</span> continue to apply
|
|
||||||
to every subsequent request.
|
|
||||||
The other methods are frames aware.
|
|
||||||
This means that if you have an individual frame that is not
|
|
||||||
loading, navigate to it using <span class="new_code">SimpleBrowser::setFrameFocus()</span>
|
|
||||||
and you can then use <span class="new_code">SimpleBrowser::getRequest()</span>, etc to
|
|
||||||
see what happened.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="unit"></a>Complex unit tests with multiple browsers</h2>
|
|
||||||
<p>
|
|
||||||
Anything that could be done in a
|
|
||||||
<a href="web_tester_documentation.html">WebTestCase</a> can
|
|
||||||
now be done in a <a href="unit_tester_documentation.html">UnitTestCase</a>.
|
|
||||||
This means that we could freely mix domain object testing with the
|
|
||||||
web interface...
|
|
||||||
<pre>
|
|
||||||
<strong>class TestOfRegistration extends UnitTestCase {
|
|
||||||
function testNewUserAddedToAuthenticator() {</strong>
|
|
||||||
$browser = new SimpleBrowser();
|
|
||||||
$browser->get('http://my-site.com/register.php');
|
|
||||||
$browser->setField('email', 'me@here');
|
|
||||||
$browser->setField('password', 'Secret');
|
|
||||||
$browser->click('Register');
|
|
||||||
<strong>
|
|
||||||
$authenticator = new Authenticator();
|
|
||||||
$member = $authenticator->findByEmail('me@here');
|
|
||||||
$this->assertEqual($member->getPassword(), 'Secret');
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
While this may be a useful temporary expediency, I am not a fan
|
|
||||||
of this type of testing.
|
|
||||||
The testing has cut across application layers, make it twice as
|
|
||||||
likely it will need refactoring when the code changes.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A more useful case of where using the browser directly can be helpful
|
|
||||||
is where the <span class="new_code">WebTestCase</span> cannot cope.
|
|
||||||
An example is where two browsers are needed at the same time.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For example, say we want to disallow multiple simultaneous
|
|
||||||
usage of a site with the same username.
|
|
||||||
This test case will do the job...
|
|
||||||
<pre>
|
|
||||||
class TestOfSecurity extends UnitTestCase {
|
|
||||||
function testNoMultipleLoginsFromSameUser() {<strong>
|
|
||||||
$first_attempt = new SimpleBrowser();
|
|
||||||
$first_attempt->get('http://my-site.com/login.php');
|
|
||||||
$first_attempt->setField('name', 'Me');
|
|
||||||
$first_attempt->setField('password', 'Secret');
|
|
||||||
$first_attempt->click('Enter');
|
|
||||||
$this->assertEqual($first_attempt->getTitle(), 'Welcome');
|
|
||||||
|
|
||||||
$second_attempt = new SimpleBrowser();
|
|
||||||
$second_attempt->get('http://my-site.com/login.php');
|
|
||||||
$second_attempt->setField('name', 'Me');
|
|
||||||
$second_attempt->setField('password', 'Secret');
|
|
||||||
$second_attempt->click('Enter');
|
|
||||||
$this->assertEqual($second_attempt->getTitle(), 'Access Denied');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
You can also use the <span class="new_code">SimpleBrowser</span> class
|
|
||||||
directly when you want to write test cases using a different
|
|
||||||
test tool than SimpleTest, such as PHPUnit.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
|
|
||||||
gives full detail on the classes and assertions available.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Scriptable browser</span>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,121 +0,0 @@
|
|||||||
body {
|
|
||||||
padding-left: 3%;
|
|
||||||
padding-right: 3%;
|
|
||||||
}
|
|
||||||
h1, h2, h3 {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
font-family: "courier new", courier, typewriter, monospace;
|
|
||||||
font-size: 90%;
|
|
||||||
border: 1px solid;
|
|
||||||
border-color: #999966;
|
|
||||||
background-color: #ffffcc;
|
|
||||||
padding: 5px;
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 40px;
|
|
||||||
}
|
|
||||||
.code, .new_code, pre.new_code {
|
|
||||||
font-family: "courier new", courier, typewriter, monospace;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
div.copyright {
|
|
||||||
font-size: 80%;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
div.copyright a {
|
|
||||||
margin-top: 1em;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
ul.api {
|
|
||||||
border: 2px outset;
|
|
||||||
border-color: gray;
|
|
||||||
background-color: white;
|
|
||||||
margin: 5px;
|
|
||||||
margin-left: 5%;
|
|
||||||
margin-right: 5%;
|
|
||||||
}
|
|
||||||
ul.api li {
|
|
||||||
margin-top: 0.2em;
|
|
||||||
margin-bottom: 0.2em;
|
|
||||||
list-style: none;
|
|
||||||
text-indent: -3em;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
div.demo {
|
|
||||||
border: 4px ridge;
|
|
||||||
border-color: gray;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px;
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 40px;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
div.demo span.fail {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
div.demo span.pass {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
div.demo h1 {
|
|
||||||
font-size: 12pt;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
div.menu {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
border: 2px outset;
|
|
||||||
border-color: gray;
|
|
||||||
background-color: white;
|
|
||||||
margin: 5px;
|
|
||||||
margin-left: 5%;
|
|
||||||
margin-right: 5%;
|
|
||||||
}
|
|
||||||
td {
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
.shell {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
pre.shell {
|
|
||||||
border: 4px ridge;
|
|
||||||
border-color: gray;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px;
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 40px;
|
|
||||||
background-color: #000100;
|
|
||||||
color: #99ff99;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
pre.file {
|
|
||||||
color: black;
|
|
||||||
border: 1px solid;
|
|
||||||
border-color: black;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px;
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 40px;
|
|
||||||
background-color: white;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
form.demo {
|
|
||||||
background-color: lightgray;
|
|
||||||
border: 4px outset;
|
|
||||||
border-color: lightgray;
|
|
||||||
padding: 10px;
|
|
||||||
margin-right: 40%;
|
|
||||||
}
|
|
||||||
dl, dd {
|
|
||||||
margin: 10px;
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
em {
|
|
||||||
font-weight: bold;
|
|
||||||
font-family: "courier new", courier, typewriter, monospace;
|
|
||||||
}
|
|
@ -1,476 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>
|
|
||||||
Extending the SimpleTest unit tester with additional expectation classes
|
|
||||||
</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Expectations</span>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Expectation documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Using expectations for
|
|
||||||
<a href="#mock">more precise testing with mock objects</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#behaviour">Changing mock object behaviour</a> with expectations
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#extending">Extending the expectations</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Underneath SimpleTest <a href="#unit">uses expectation classes</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="mock"></a>More control over mock objects</h2>
|
|
||||||
<p>
|
|
||||||
The default behaviour of the
|
|
||||||
<a href="mock_objects_documentation.html">mock objects</a>
|
|
||||||
in
|
|
||||||
<a href="http://sourceforge.net/projects/simpletest/">SimpleTest</a>
|
|
||||||
is either an identical match on the argument or to allow any argument at all.
|
|
||||||
For almost all tests this is sufficient.
|
|
||||||
Sometimes, though, you want to weaken a test case.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
One place where a test can be too tightly coupled is with
|
|
||||||
text matching.
|
|
||||||
Suppose we have a component that outputs a helpful error
|
|
||||||
message when something goes wrong.
|
|
||||||
You want to test that the correct error was sent, but the actual
|
|
||||||
text may be rather long.
|
|
||||||
If you test for the text exactly, then every time the exact wording
|
|
||||||
of the message changes, you will have to go back and edit the test suite.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For example, suppose we have a news service that has failed
|
|
||||||
to connect to its remote source.
|
|
||||||
<pre>
|
|
||||||
<strong>class NewsService {
|
|
||||||
...
|
|
||||||
function publish($writer) {
|
|
||||||
if (! $this->isConnected()) {
|
|
||||||
$writer->write('Cannot connect to news service "' .
|
|
||||||
$this->_name . '" at this time. ' .
|
|
||||||
'Please try again later.');
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
Here it is sending its content to a
|
|
||||||
<span class="new_code">Writer</span> class.
|
|
||||||
We could test this behaviour with a
|
|
||||||
<span class="new_code">MockWriter</span> like so...
|
|
||||||
<pre>
|
|
||||||
class TestOfNewsService extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnectionFailure() {<strong>
|
|
||||||
$writer = new MockWriter();
|
|
||||||
$writer->expectOnce('write', array(
|
|
||||||
'Cannot connect to news service ' .
|
|
||||||
'"BBC News" at this time. ' .
|
|
||||||
'Please try again later.'));
|
|
||||||
|
|
||||||
$service = new NewsService('BBC News');
|
|
||||||
$service->publish($writer);</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This is a good example of a brittle test.
|
|
||||||
If we decide to add additional instructions, such as
|
|
||||||
suggesting an alternative news source, we will break
|
|
||||||
our tests even though no underlying functionality
|
|
||||||
has been altered.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To get around this, we would like to do a regular expression
|
|
||||||
test rather than an exact match.
|
|
||||||
We can actually do this with...
|
|
||||||
<pre>
|
|
||||||
class TestOfNewsService extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnectionFailure() {
|
|
||||||
$writer = new MockWriter();<strong>
|
|
||||||
$writer->expectOnce(
|
|
||||||
'write',
|
|
||||||
array(new PatternExpectation('/cannot connect/i')));</strong>
|
|
||||||
|
|
||||||
$service = new NewsService('BBC News');
|
|
||||||
$service->publish($writer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Instead of passing in the expected parameter to the
|
|
||||||
<span class="new_code">MockWriter</span> we pass an
|
|
||||||
expectation class called
|
|
||||||
<span class="new_code">PatternExpectation</span>.
|
|
||||||
The mock object is smart enough to recognise this as special
|
|
||||||
and to treat it differently.
|
|
||||||
Rather than simply comparing the incoming argument to this
|
|
||||||
object, it uses the expectation object itself to
|
|
||||||
perform the test.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The <span class="new_code">PatternExpectation</span> takes
|
|
||||||
the regular expression to match in its constructor.
|
|
||||||
Whenever a comparison is made by the <span class="new_code">MockWriter</span>
|
|
||||||
against this expectation class, it will do a
|
|
||||||
<span class="new_code">preg_match()</span> with this pattern.
|
|
||||||
With our test case above, as long as "cannot connect"
|
|
||||||
appears in the text of the string, the mock will issue a pass
|
|
||||||
to the unit tester.
|
|
||||||
The rest of the text does not matter.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The possible expectation classes are...
|
|
||||||
<table><tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">AnythingExpectation</span></td>
|
|
||||||
<td>Will always match</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">EqualExpectation</span></td>
|
|
||||||
<td>An equality, rather than the stronger identity comparison</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">NotEqualExpectation</span></td>
|
|
||||||
<td>An inequality comparison</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">IndenticalExpectation</span></td>
|
|
||||||
<td>The default mock object check which must match exactly</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">NotIndenticalExpectation</span></td>
|
|
||||||
<td>Inverts the mock object logic</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">WithinMarginExpectation</span></td>
|
|
||||||
<td>Compares a value to within a margin</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">OutsideMarginExpectation</span></td>
|
|
||||||
<td>Checks that a value is out side the margin</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">PatternExpectation</span></td>
|
|
||||||
<td>Uses a Perl Regex to match a string</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">NoPatternExpectation</span></td>
|
|
||||||
<td>Passes only if failing a Perl Regex</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">IsAExpectation</span></td>
|
|
||||||
<td>Checks the type or class name only</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">NotAExpectation</span></td>
|
|
||||||
<td>Opposite of the <span class="new_code">IsAExpectation</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">MethodExistsExpectation</span></td>
|
|
||||||
<td>Checks a method is available on an object</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">TrueExpectation</span></td>
|
|
||||||
<td>Accepts any PHP variable that evaluates to true</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">FalseExpectation</span></td>
|
|
||||||
<td>Accepts any PHP variable that evaluates to false</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
Most take the expected value in the constructor.
|
|
||||||
The exceptions are the pattern matchers, which take a regular expression,
|
|
||||||
and the <span class="new_code">IsAExpectation</span> and <span class="new_code">NotAExpectation</span> which takes a type
|
|
||||||
or class name as a string.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Some examples...
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<pre>
|
|
||||||
$mock->expectOnce('method', array(new IdenticalExpectation(14)));
|
|
||||||
</pre>
|
|
||||||
This is the same as <span class="new_code">$mock->expectOnce('method', array(14))</span>.
|
|
||||||
<pre>
|
|
||||||
$mock->expectOnce('method', array(new EqualExpectation(14)));
|
|
||||||
</pre>
|
|
||||||
This is different from the previous version in that the string
|
|
||||||
<span class="new_code">"14"</span> as a parameter will also pass.
|
|
||||||
Sometimes the additional type checks of SimpleTest are too restrictive.
|
|
||||||
<pre>
|
|
||||||
$mock->expectOnce('method', array(new AnythingExpectation(14)));
|
|
||||||
</pre>
|
|
||||||
This is the same as <span class="new_code">$mock->expectOnce('method', array('*'))</span>.
|
|
||||||
<pre>
|
|
||||||
$mock->expectOnce('method', array(new IdenticalExpectation('*')));
|
|
||||||
</pre>
|
|
||||||
This is handy if you want to assert a literal <span class="new_code">"*"</span>.
|
|
||||||
<pre>
|
|
||||||
new NotIdenticalExpectation(14)
|
|
||||||
</pre>
|
|
||||||
This matches on anything other than integer 14.
|
|
||||||
Even the string <span class="new_code">"14"</span> would pass.
|
|
||||||
<pre>
|
|
||||||
new WithinMarginExpectation(14.0, 0.001)
|
|
||||||
</pre>
|
|
||||||
This will accept any value from 13.999 to 14.001 inclusive.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="behaviour"></a>Using expectations to control stubs</h2>
|
|
||||||
<p>
|
|
||||||
The expectation classes can be used not just for sending assertions
|
|
||||||
from mock objects, but also for selecting behaviour for the
|
|
||||||
<a href="mock_objects_documentation.html">mock objects</a>.
|
|
||||||
Anywhere a list of arguments is given, a list of expectation objects
|
|
||||||
can be inserted instead.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Suppose we want a mock authorisation server to simulate a successful login,
|
|
||||||
but only if it receives a valid session object.
|
|
||||||
We can do this as follows...
|
|
||||||
<pre>
|
|
||||||
Mock::generate('Authorisation');
|
|
||||||
<strong>
|
|
||||||
$authorisation = new MockAuthorisation();
|
|
||||||
$authorisation->returns(
|
|
||||||
'isAllowed',
|
|
||||||
true,
|
|
||||||
array(new IsAExpectation('Session', 'Must be a session')));
|
|
||||||
$authorisation->returns('isAllowed', false);</strong>
|
|
||||||
</pre>
|
|
||||||
We have set the default mock behaviour to return false when
|
|
||||||
<span class="new_code">isAllowed</span> is called.
|
|
||||||
When we call the method with a single parameter that
|
|
||||||
is a <span class="new_code">Session</span> object, it will return true.
|
|
||||||
We have also added a second parameter as a message.
|
|
||||||
This will be displayed as part of the mock object
|
|
||||||
failure message if this expectation is the cause of
|
|
||||||
a failure.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This kind of sophistication is rarely useful, but is included for
|
|
||||||
completeness.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="extending"></a>Creating your own expectations</h2>
|
|
||||||
<p>
|
|
||||||
The expectation classes have a very simple structure.
|
|
||||||
So simple that it is easy to create your own versions for
|
|
||||||
commonly used test logic.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
As an example here is the creation of a class to test for
|
|
||||||
valid IP addresses.
|
|
||||||
In order to work correctly with the stubs and mocks the new
|
|
||||||
expectation class should extend
|
|
||||||
<span class="new_code">SimpleExpectation</span> or further extend a subclass...
|
|
||||||
<pre>
|
|
||||||
<strong>class ValidIp extends SimpleExpectation {
|
|
||||||
|
|
||||||
function test($ip) {
|
|
||||||
return (ip2long($ip) != -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testMessage($ip) {
|
|
||||||
return "Address [$ip] should be a valid IP address";
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
There are only two methods to implement.
|
|
||||||
The <span class="new_code">test()</span> method should
|
|
||||||
evaluate to true if the expectation is to pass, and
|
|
||||||
false otherwise.
|
|
||||||
The <span class="new_code">testMessage()</span> method
|
|
||||||
should simply return some helpful text explaining the test
|
|
||||||
that was carried out.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This class can now be used in place of the earlier expectation
|
|
||||||
classes.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here is a more typical example, matching part of a hash...
|
|
||||||
<pre>
|
|
||||||
<strong>class JustField extends EqualExpectation {
|
|
||||||
private $key;
|
|
||||||
|
|
||||||
function __construct($key, $expected) {
|
|
||||||
parent::__construct($expected);
|
|
||||||
$this->key = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
function test($compare) {
|
|
||||||
if (! isset($compare[$this->key])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return parent::test($compare[$this->key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testMessage($compare) {
|
|
||||||
if (! isset($compare[$this->key])) {
|
|
||||||
return 'Key [' . $this->key . '] does not exist';
|
|
||||||
}
|
|
||||||
return 'Key [' . $this->key . '] -> ' .
|
|
||||||
parent::testMessage($compare[$this->key]);
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
We tend to seperate message clauses with
|
|
||||||
"&nbsp;->&nbsp;".
|
|
||||||
This allows derivative tools to reformat the output.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Suppose some authenticator is expecting to be given
|
|
||||||
a database row corresponding to the user, and we
|
|
||||||
only need to confirm the username is correct.
|
|
||||||
We can assert just their username with...
|
|
||||||
<pre>
|
|
||||||
$mock->expectOnce('authenticate',
|
|
||||||
array(new JustKey('username', 'marcus')));
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="unit"></a>Under the bonnet of the unit tester</h2>
|
|
||||||
<p>
|
|
||||||
The <a href="http://sourceforge.net/projects/simpletest/">SimpleTest unit testing framework</a>
|
|
||||||
also uses the expectation classes internally for the
|
|
||||||
<a href="unit_test_documentation.html">UnitTestCase class</a>.
|
|
||||||
We can also take advantage of these mechanisms to reuse our
|
|
||||||
homebrew expectation classes within the test suites directly.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The most crude way of doing this is to use the generic
|
|
||||||
<span class="new_code">SimpleTest::assert()</span> method to
|
|
||||||
test against it directly...
|
|
||||||
<pre>
|
|
||||||
<strong>class TestOfNetworking extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testGetValidIp() {
|
|
||||||
$server = &new Server();
|
|
||||||
$this->assert(
|
|
||||||
new ValidIp(),
|
|
||||||
$server->getIp(),
|
|
||||||
'Server IP address->%s');
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
<span class="new_code">assert()</span> will test any expectation class directly.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This is a little untidy compared with our usual
|
|
||||||
<span class="new_code">assert...()</span> syntax.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For such a simple case we would normally create a
|
|
||||||
separate assertion method on our test case rather
|
|
||||||
than bother using the expectation class.
|
|
||||||
If we pretend that our expectation is a little more
|
|
||||||
complicated for a moment, so that we want to reuse it,
|
|
||||||
we get...
|
|
||||||
<pre>
|
|
||||||
class TestOfNetworking extends UnitTestCase {
|
|
||||||
...<strong>
|
|
||||||
function assertValidIp($ip, $message = '%s') {
|
|
||||||
$this->assert(new ValidIp(), $ip, $message);
|
|
||||||
}</strong>
|
|
||||||
|
|
||||||
function testGetValidIp() {
|
|
||||||
$server = &new Server();<strong>
|
|
||||||
$this->assertValidIp(
|
|
||||||
$server->getIp(),
|
|
||||||
'Server IP address->%s');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
It is rare to need the expectations for more than pattern
|
|
||||||
matching, but these facilities do allow testers to build
|
|
||||||
some sort of domain language for testing their application.
|
|
||||||
Also, complex expectation classes could make the tests
|
|
||||||
harder to read and debug.
|
|
||||||
In effect extending the test framework to create their own tool set.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The expectations mimic the constraints in <a href="http://www.jmock.org/">JMock</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="http://simpletest.org/api/">Full API for SimpleTest</a>
|
|
||||||
from the PHPDoc.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Expectations</span>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,351 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest documentation for testing HTML forms</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Testing forms</span>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Form testing documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Changing form values and successfully
|
|
||||||
<a href="#submit">Submitting a simple form</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Handling <a href="#multiple">widgets with multiple values</a>
|
|
||||||
by setting lists.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Bypassing javascript to <a href="#hidden-field">set a hidden field</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#raw">Raw posting</a> when you don't have a button
|
|
||||||
to click.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="submit"></a>Submitting a simple form</h2>
|
|
||||||
<p>
|
|
||||||
When a page is fetched by the <span class="new_code">WebTestCase</span>
|
|
||||||
using <span class="new_code">get()</span> or
|
|
||||||
<span class="new_code">post()</span> the page content is
|
|
||||||
automatically parsed.
|
|
||||||
This results in any form controls that are inside <form> tags
|
|
||||||
being available from within the test case.
|
|
||||||
For example, if we have this snippet of HTML...
|
|
||||||
<pre>
|
|
||||||
<form>
|
|
||||||
<input type="text" name="a" value="A default" />
|
|
||||||
<input type="submit" value="Go" />
|
|
||||||
</form>
|
|
||||||
</pre>
|
|
||||||
Which looks like this...
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<form class="demo">
|
|
||||||
<input type="text" name="a" value="A default">
|
|
||||||
<input type="submit" value="Go">
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We can navigate to this code, via the
|
|
||||||
<a href="http://www.lastcraft.com/form_testing_documentation.php">LastCraft</a>
|
|
||||||
site, with the following test...
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {<strong>
|
|
||||||
function testDefaultValue() {
|
|
||||||
$this->get('http://www.lastcraft.com/form_testing_documentation.php');
|
|
||||||
$this->assertField('a', 'A default');
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Immediately after loading the page all of the HTML controls are set at
|
|
||||||
their default values just as they would appear in the web browser.
|
|
||||||
The assertion tests that a HTML widget exists in the page with the
|
|
||||||
name "a" and that it is currently set to the value
|
|
||||||
"A default".
|
|
||||||
As usual, we could use a pattern expectation instead of a fixed
|
|
||||||
string.
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
function testDefaultValue() {
|
|
||||||
$this->get('http://www.lastcraft.com/form_testing_documentation.php');
|
|
||||||
$this->assertField('a', <strong>new PatternExpectation('/default/')</strong>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
We could submit the form straight away, but first we'll change
|
|
||||||
the value of the text field and only then submit it...
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
function testDefaultValue() {
|
|
||||||
$this->get('http://www.my-site.com/');
|
|
||||||
$this->assertField('a', 'A default');<strong>
|
|
||||||
$this->setField('a', 'New value');
|
|
||||||
$this->click('Go');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Because we didn't specify a method attribute on the form tag, and
|
|
||||||
didn't specify an action either, the test case will follow
|
|
||||||
the usual browser behaviour of submitting the form data as a <em>GET</em>
|
|
||||||
request back to the same location.
|
|
||||||
In general SimpleTest tries to emulate typical browser behaviour as much as possible,
|
|
||||||
rather than attempting to catch any form of HTML omission.
|
|
||||||
This is because the target of the testing framework is the PHP application
|
|
||||||
logic, not syntax or other errors in the HTML code.
|
|
||||||
For HTML errors, other tools such as
|
|
||||||
<a href="http://www.w3.org/People/Raggett/tidy/">HTMLTidy</a> should be used,
|
|
||||||
or any of the HTML and CSS validators already out there.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If a field is not present in any form, or if an option is unavailable,
|
|
||||||
then <span class="new_code">WebTestCase::setField()</span> will return
|
|
||||||
<span class="new_code">false</span>.
|
|
||||||
For example, suppose we wish to verify that a "Superuser"
|
|
||||||
option is not present in this form...
|
|
||||||
<pre>
|
|
||||||
<strong>Select type of user to add:</strong>
|
|
||||||
<select name="type">
|
|
||||||
<option>Subscriber</option>
|
|
||||||
<option>Author</option>
|
|
||||||
<option>Administrator</option>
|
|
||||||
</select>
|
|
||||||
</pre>
|
|
||||||
Which looks like...
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<form class="demo">
|
|
||||||
<strong>Select type of user to add:</strong>
|
|
||||||
<select name="type">
|
|
||||||
<option>Subscriber</option>
|
|
||||||
<option>Author</option>
|
|
||||||
<option>Administrator</option>
|
|
||||||
</select>
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The following test will confirm it...
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
...
|
|
||||||
function testNoSuperuserChoiceAvailable() {<strong>
|
|
||||||
$this->get('http://www.lastcraft.com/form_testing_documentation.php');
|
|
||||||
$this->assertFalse($this->setField('type', 'Superuser'));</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The current selection will not be changed if the new value is not an option.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here is the full list of widgets currently supported...
|
|
||||||
<ul>
|
|
||||||
<li>Text fields, including hidden and password fields.</li>
|
|
||||||
<li>Submit buttons including the button tag, although not yet reset buttons</li>
|
|
||||||
<li>Text area. This includes text wrapping behaviour.</li>
|
|
||||||
<li>Checkboxes, including multiple checkboxes in the same form.</li>
|
|
||||||
<li>Drop down selections, including multiple selects.</li>
|
|
||||||
<li>Radio buttons.</li>
|
|
||||||
<li>Images.</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The browser emulation offered by SimpleTest mimics
|
|
||||||
the actions which can be perform by a user on a
|
|
||||||
standard HTML page. Javascript is not supported, and
|
|
||||||
it's unlikely that support will be added any time
|
|
||||||
soon.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Of particular note is that the Javascript idiom of
|
|
||||||
passing form results by setting a hidden field cannot
|
|
||||||
be performed using the normal SimpleTest
|
|
||||||
commands. See below for a way to test such forms.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="multiple"></a>Fields with multiple values</h2>
|
|
||||||
<p>
|
|
||||||
SimpleTest can cope with two types of multivalue controls: Multiple
|
|
||||||
selection drop downs, and multiple checkboxes with the same name
|
|
||||||
within a form.
|
|
||||||
The multivalue nature of these means that setting and testing
|
|
||||||
are slightly different.
|
|
||||||
Using checkboxes as an example...
|
|
||||||
<pre>
|
|
||||||
<form class="demo">
|
|
||||||
<strong>Create privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="c" checked><br>
|
|
||||||
<strong>Retrieve privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="r" checked><br>
|
|
||||||
<strong>Update privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="u" checked><br>
|
|
||||||
<strong>Destroy privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="d" checked><br>
|
|
||||||
<input type="submit" value="Enable Privileges">
|
|
||||||
</form>
|
|
||||||
</pre>
|
|
||||||
Which renders as...
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<form class="demo">
|
|
||||||
<strong>Create privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="c" checked><br>
|
|
||||||
<strong>Retrieve privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="r" checked><br>
|
|
||||||
<strong>Update privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="u" checked><br>
|
|
||||||
<strong>Destroy privileges allowed:</strong>
|
|
||||||
<input type="checkbox" name="crud" value="d" checked><br>
|
|
||||||
<input type="submit" value="Enable Privileges">
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If we wish to disable all but the retrieval privileges and
|
|
||||||
submit this information we can do it like this...
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
...<strong>
|
|
||||||
function testDisableNastyPrivileges() {
|
|
||||||
$this->get('http://www.lastcraft.com/form_testing_documentation.php');
|
|
||||||
$this->assertField('crud', array('c', 'r', 'u', 'd'));
|
|
||||||
$this->setField('crud', array('r'));
|
|
||||||
$this->click('Enable Privileges');
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Instead of setting the field to a single value, we give it a list
|
|
||||||
of values.
|
|
||||||
We do the same when testing expected values.
|
|
||||||
We can then write other test code to confirm the effect of this, perhaps
|
|
||||||
by logging in as that user and attempting an update.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="hidden-field"></a>Forms which use javascript to set a hidden field</h2>
|
|
||||||
<p>
|
|
||||||
If you want to test a form which relies on javascript to set a hidden
|
|
||||||
field, you can't just call setField().
|
|
||||||
The following code will <em>not</em> work:
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
function testEmulateMyJavascriptForm() {
|
|
||||||
<strong>// This does *not* work</strong>
|
|
||||||
$this->setField('a_hidden_field', '123');
|
|
||||||
$this->clickSubmit('OK');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Instead, you need to pass the additional form parameters to the
|
|
||||||
clickSubmit() method:
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
function testMyJavascriptForm() {
|
|
||||||
<strong>$this->clickSubmit('OK', array('a_hidden_field'=>'123'));</strong>
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Bear in mind that in doing this you're effectively stubbing out a
|
|
||||||
part of your software (the javascript code in the form), and
|
|
||||||
perhaps you might be better off using something like
|
|
||||||
<a href="http://selenium.openqa.org/">Selenium</a> to ensure a complete
|
|
||||||
test.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="raw"></a>Raw posting</h2>
|
|
||||||
<p>
|
|
||||||
If you want to test a form handler, but have not yet written
|
|
||||||
or do not have access to the form itself, you can create a
|
|
||||||
form submission by hand.
|
|
||||||
<pre>
|
|
||||||
class SimpleFormTests extends WebTestCase {
|
|
||||||
...<strong>
|
|
||||||
function testAttemptedHack() {
|
|
||||||
$this->post(
|
|
||||||
'http://www.my-site.com/add_user.php',
|
|
||||||
array('type' => 'superuser'));
|
|
||||||
$this->assertNoText('user created');
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
By adding data to the <span class="new_code">WebTestCase::post()</span>
|
|
||||||
method, we are emulating a form submission.
|
|
||||||
You would normally only do this as a temporary expedient, or where
|
|
||||||
you are expecting a 3rd party to submit to a form.
|
|
||||||
The exception is when you want tests to protect you from
|
|
||||||
attempts to spoof your pages.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
|
|
||||||
gives full detail on the classes and assertions available.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Testing forms</span>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,252 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest for PHP test suites</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Group tests</span>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Test suite documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Different ways to <a href="#group">group tests</a> together.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Combining group tests into <a href="#higher">larger groups</a>.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="group"></a>Grouping tests into suites</h2>
|
|
||||||
<p>
|
|
||||||
There are many ways to group tests together into test suites.
|
|
||||||
One way is to simply place multiple test cases into a single file...
|
|
||||||
<pre>
|
|
||||||
<strong><?php
|
|
||||||
require_once(dirname(__FILE__) . '/simpletest/autorun.php');
|
|
||||||
require_once(dirname(__FILE__) . '/../classes/io.php');
|
|
||||||
|
|
||||||
class FileTester extends UnitTestCase {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
class SocketTester extends UnitTestCase {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
?></strong>
|
|
||||||
</pre>
|
|
||||||
As many cases as needed can appear in a single file.
|
|
||||||
They should include any code they need, such as the library
|
|
||||||
being tested, but need none of the SimpleTest libraries.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Occasionally special subclasses are created that methods useful
|
|
||||||
for testing part of the application.
|
|
||||||
These new base classes are then used in place of <span class="new_code">UnitTestCase</span>
|
|
||||||
or <span class="new_code">WebTestCase</span>.
|
|
||||||
You don't normally want to run these as test cases.
|
|
||||||
Simply mark any base test cases that should not be run as abstract...
|
|
||||||
<pre>
|
|
||||||
<strong>abstract</strong> class MyFileTestCase extends UnitTestCase {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
class FileTester extends MyFileTestCase { ... }
|
|
||||||
|
|
||||||
class SocketTester extends UnitTestCase { ... }
|
|
||||||
</pre>
|
|
||||||
Here the <span class="new_code">FileTester</span> class does
|
|
||||||
not contain any actual tests, but is the base class for other
|
|
||||||
test cases.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We will call this sample <em>file_test.php</em>.
|
|
||||||
Currently the test cases are grouped simply by being in the same file.
|
|
||||||
We can build larger constructs just by including other test files in.
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
require_once('file_test.php');
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This will work, but create a purely flat hierarchy.
|
|
||||||
INstead we create a test suite file.
|
|
||||||
Our top level test suite can look like this...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
class AllFileTests extends TestSuite {
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
<strong>$this->addFile('file_test.php');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
What happens here is that the <span class="new_code">TestSuite</span>
|
|
||||||
class will do the <span class="new_code">require_once()</span>
|
|
||||||
for us.
|
|
||||||
It then checks to see if any new test case classes
|
|
||||||
have been created by the new file and automatically composes
|
|
||||||
them to the test suite.
|
|
||||||
This method gives us the most control as we just manually add
|
|
||||||
more test files as our test suite grows.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If this is too much typing, and you are willing to group
|
|
||||||
test suites together in their own directories or otherwise
|
|
||||||
tag the file names, then there is a more automatic way...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
class AllFileTests extends TestSuite {
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->collect(dirname(__FILE__) . '/unit',
|
|
||||||
new SimplePatternCollector('/_test.php/'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This will scan a directory called "unit" for any files
|
|
||||||
ending with "_test.php" and load them.
|
|
||||||
You don't have to use <span class="new_code">SimplePatternCollector</span> to
|
|
||||||
filter by a pattern in the filename, but this is the most common
|
|
||||||
usage.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
That snippet above is very common in practice.
|
|
||||||
Now all you have to do is drop a file of test cases into the
|
|
||||||
directory and it will run just by running the test suite script.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The catch is that you cannot control the order in which the test
|
|
||||||
cases are run.
|
|
||||||
If you want to see lower level components fail first in the test suite,
|
|
||||||
and this will make diagnosis a lot easier, then you should manually
|
|
||||||
call <span class="new_code">addFile()</span> for these.
|
|
||||||
Tests cases are only loaded once, so it's fine to have these included
|
|
||||||
again by a directory scan.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Test cases loaded with the <span class="new_code">addFile</span> method have some
|
|
||||||
useful properties.
|
|
||||||
You can guarantee that the constructor is run
|
|
||||||
just before the first test method and the destructor
|
|
||||||
is run just after the last test method.
|
|
||||||
This allows you to place test case wide set up and tear down
|
|
||||||
code in the constructor and destructor, just like a normal
|
|
||||||
class.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="higher"></a>Composite suites</h2>
|
|
||||||
<p>
|
|
||||||
The above method places all of the test cases into one large suite.
|
|
||||||
For larger projects though this may not be flexible enough; you
|
|
||||||
may want to group the tests together in all sorts of ways.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Everything we have described so far with test scripts applies to
|
|
||||||
<span class="new_code">TestSuite</span>s as well...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
<strong>
|
|
||||||
class BigTestSuite extends TestSuite {
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->addFile('file_tests.php');
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This effectively adds our test cases and a single suite below
|
|
||||||
the first.
|
|
||||||
When a test fails, we see the breadcrumb trail of the nesting.
|
|
||||||
We can even mix groups and test cases freely as long as
|
|
||||||
we are careful about loops in our includes.
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
class BigTestSuite extends TestSuite {
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->addFile('file_tests.php');
|
|
||||||
<strong>$this->addFile('some_other_test.php');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
Note that in the event of a double include, ony the first instance
|
|
||||||
of the test case will be run.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Group tests</span>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,870 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest for PHP mock objects documentation</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Mock objects</span>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Mock objects documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="#what">What are mock objects?</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#creation">Creating mock objects</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#expectations">Mocks as critics</a> with expectations.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="what"></a>What are mock objects?</h2>
|
|
||||||
<p>
|
|
||||||
Mock objects have two roles during a test case: actor and critic.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The actor behaviour is to simulate objects that are difficult to
|
|
||||||
set up or time consuming to set up for a test.
|
|
||||||
The classic example is a database connection.
|
|
||||||
Setting up a test database at the start of each test would slow
|
|
||||||
testing to a crawl and would require the installation of the
|
|
||||||
database engine and test data on the test machine.
|
|
||||||
If we can simulate the connection and return data of our
|
|
||||||
choosing we not only win on the pragmatics of testing, but can
|
|
||||||
also feed our code spurious data to see how it responds.
|
|
||||||
We can simulate databases being down or other extremes
|
|
||||||
without having to create a broken database for real.
|
|
||||||
In other words, we get greater control of the test environment.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If mock objects only behaved as actors they would simply be
|
|
||||||
known as "server stubs".
|
|
||||||
This was originally a pattern named by Robert Binder (<a href="">Testing
|
|
||||||
object-oriented systems</a>: models, patterns, and tools,
|
|
||||||
Addison-Wesley) in 1999.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A server stub is a simulation of an object or component.
|
|
||||||
It should exactly replace a component in a system for test
|
|
||||||
or prototyping purposes, but remain lightweight.
|
|
||||||
This allows tests to run more quickly, or if the simulated
|
|
||||||
class has not been written, to run at all.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
However, the mock objects not only play a part (by supplying chosen
|
|
||||||
return values on demand) they are also sensitive to the
|
|
||||||
messages sent to them (via expectations).
|
|
||||||
By setting expected parameters for a method call they act
|
|
||||||
as a guard that the calls upon them are made correctly.
|
|
||||||
If expectations are not met they save us the effort of
|
|
||||||
writing a failed test assertion by performing that duty on our
|
|
||||||
behalf.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In the case of an imaginary database connection they can
|
|
||||||
test that the query, say SQL, was correctly formed by
|
|
||||||
the object that is using the connection.
|
|
||||||
Set them up with fairly tight expectations and you will
|
|
||||||
hardly need manual assertions at all.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="creation"></a>Creating mock objects</h2>
|
|
||||||
<p>
|
|
||||||
All we need is an existing class or interface, say a database connection
|
|
||||||
that looks like this...
|
|
||||||
<pre>
|
|
||||||
<strong>class DatabaseConnection {
|
|
||||||
function DatabaseConnection() { }
|
|
||||||
function query($sql) { }
|
|
||||||
function selectQuery($sql) { }
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
To create a mock version of the class we need to run a
|
|
||||||
code generator...
|
|
||||||
<pre>
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
require_once('database_connection.php');
|
|
||||||
|
|
||||||
<strong>Mock::generate('DatabaseConnection');</strong>
|
|
||||||
</pre>
|
|
||||||
This code generates a clone class called
|
|
||||||
<span class="new_code">MockDatabaseConnection</span>.
|
|
||||||
This new class appears to be the same, but actually has no behaviour at all.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The new class is usually a subclass of <span class="new_code">DatabaseConnection</span>.
|
|
||||||
Unfortunately, there is no way to create a mock version of a
|
|
||||||
class with a <span class="new_code">final</span> method without having a living version of
|
|
||||||
that method.
|
|
||||||
We consider that unsafe.
|
|
||||||
If the target is an interface, or if <span class="new_code">final</span> methods are
|
|
||||||
present in a target class, then a whole new class
|
|
||||||
is created, but one implemeting the same interfaces.
|
|
||||||
If you try to pass this separate class through a type hint that specifies
|
|
||||||
the old concrete class name, it will fail.
|
|
||||||
Code like that insists on type hinting to a class with <span class="new_code">final</span>
|
|
||||||
methods probably cannot be safely tested with mocks.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you want to see the generated code, then simply <span class="new_code">print</span>
|
|
||||||
the output of <span class="new_code">Mock::generate()</span>.
|
|
||||||
Here is the generated code for the <span class="new_code">DatabaseConnection</span>
|
|
||||||
class rather than the interface version...
|
|
||||||
<pre>
|
|
||||||
class MockDatabaseConnection extends DatabaseConnection {
|
|
||||||
public $mock;
|
|
||||||
protected $mocked_methods = array('databaseconnection', 'query', 'selectquery');
|
|
||||||
|
|
||||||
function MockDatabaseConnection() {
|
|
||||||
$this->mock = new SimpleMock();
|
|
||||||
$this->mock->disableExpectationNameChecks();
|
|
||||||
}
|
|
||||||
...
|
|
||||||
function DatabaseConnection() {
|
|
||||||
$args = func_get_args();
|
|
||||||
$result = &$this->mock->invoke("DatabaseConnection", $args);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
function query($sql) {
|
|
||||||
$args = func_get_args();
|
|
||||||
$result = &$this->mock->invoke("query", $args);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
function selectQuery($sql) {
|
|
||||||
$args = func_get_args();
|
|
||||||
$result = &$this->mock->invoke("selectQuery", $args);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Your output may vary depending on the exact version
|
|
||||||
of SimpleTest you are using.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Besides the original methods of the class, you will see some extra
|
|
||||||
methods that help testing.
|
|
||||||
More on these later.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We can now create instances of the new class within
|
|
||||||
our test case...
|
|
||||||
<pre>
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
require_once('database_connection.php');
|
|
||||||
|
|
||||||
Mock::generate('DatabaseConnection');
|
|
||||||
|
|
||||||
class MyTestCase extends UnitTestCase {
|
|
||||||
|
|
||||||
function testSomething() {
|
|
||||||
<strong>$connection = new MockDatabaseConnection();</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The mock version now has all the methods of the original.
|
|
||||||
Also, any type hints will be faithfully preserved.
|
|
||||||
Say our query methods expect a <span class="new_code">Query</span> object...
|
|
||||||
<pre>
|
|
||||||
<strong>class DatabaseConnection {
|
|
||||||
function DatabaseConnection() { }
|
|
||||||
function query(Query $query) { }
|
|
||||||
function selectQuery(Query $query) { }
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
If we now pass the wrong type of object, or worse a non-object...
|
|
||||||
<pre>
|
|
||||||
class MyTestCase extends UnitTestCase {
|
|
||||||
|
|
||||||
function testSomething() {
|
|
||||||
$connection = new MockDatabaseConnection();
|
|
||||||
$connection->query('insert into accounts () values ()');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
...the code will throw a type violation at you just as the
|
|
||||||
original class would.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The mock version now has all the methods of the original.
|
|
||||||
Unfortunately, they all return <span class="new_code">null</span>.
|
|
||||||
As methods that always return <span class="new_code">null</span> are not that useful,
|
|
||||||
we need to be able to set them to something else...
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a class="target" name="stub"><h2>Mocks as actors</h2></a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Changing the return value of a method from <span class="new_code">null</span>
|
|
||||||
to something else is pretty easy...
|
|
||||||
<pre>
|
|
||||||
<strong>$connection->returns('query', 37)</strong>
|
|
||||||
</pre>
|
|
||||||
Now every time we call
|
|
||||||
<span class="new_code">$connection->query()</span> we get
|
|
||||||
the result of 37.
|
|
||||||
There is nothing special about 37.
|
|
||||||
The return value can be arbitrarily complicated.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Parameters are irrelevant here, we always get the same
|
|
||||||
values back each time once they have been set up this way.
|
|
||||||
That may not sound like a convincing replica of a
|
|
||||||
database connection, but for the half a dozen lines of
|
|
||||||
a test method it is usually all you need.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Things aren't always that simple though.
|
|
||||||
One common problem is iterators, where constantly returning
|
|
||||||
the same value could cause an endless loop in the object
|
|
||||||
being tested.
|
|
||||||
For these we need to set up sequences of values.
|
|
||||||
Let's say we have a simple iterator that looks like this...
|
|
||||||
<pre>
|
|
||||||
class Iterator {
|
|
||||||
function Iterator() { }
|
|
||||||
function next() { }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This is about the simplest iterator you could have.
|
|
||||||
Assuming that this iterator only returns text until it
|
|
||||||
reaches the end, when it returns false, we can simulate it
|
|
||||||
with...
|
|
||||||
<pre>
|
|
||||||
Mock::generate('Iterator');
|
|
||||||
|
|
||||||
class IteratorTest extends UnitTestCase() {
|
|
||||||
|
|
||||||
function testASequence() {<strong>
|
|
||||||
$iterator = new MockIterator();
|
|
||||||
$iterator->returns('next', false);
|
|
||||||
$iterator->returnsAt(0, 'next', 'First string');
|
|
||||||
$iterator->returnsAt(1, 'next', 'Second string');</strong>
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
When <span class="new_code">next()</span> is called on the
|
|
||||||
<span class="new_code">MockIterator</span> it will first return "First string",
|
|
||||||
on the second call "Second string" will be returned
|
|
||||||
and on any other call <span class="new_code">false</span> will
|
|
||||||
be returned.
|
|
||||||
The sequenced return values take precedence over the constant
|
|
||||||
return value.
|
|
||||||
The constant one is a kind of default if you like.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Another tricky situation is an overloaded
|
|
||||||
<span class="new_code">get()</span> operation.
|
|
||||||
An example of this is an information holder with name/value pairs.
|
|
||||||
Say we have a configuration class like...
|
|
||||||
<pre>
|
|
||||||
class Configuration {
|
|
||||||
function Configuration() { ... }
|
|
||||||
function get($key) { ... }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This is a likely situation for using mock objects, as
|
|
||||||
actual configuration will vary from machine to machine and
|
|
||||||
even from test to test.
|
|
||||||
The problem though is that all the data comes through the
|
|
||||||
<span class="new_code">get()</span> method and yet
|
|
||||||
we want different results for different keys.
|
|
||||||
Luckily the mocks have a filter system...
|
|
||||||
<pre>
|
|
||||||
<strong>$config = &new MockConfiguration();
|
|
||||||
$config->returns('get', 'primary', array('db_host'));
|
|
||||||
$config->returns('get', 'admin', array('db_user'));
|
|
||||||
$config->returns('get', 'secret', array('db_password'));</strong>
|
|
||||||
</pre>
|
|
||||||
The extra parameter is a list of arguments to attempt
|
|
||||||
to match.
|
|
||||||
In this case we are trying to match only one argument which
|
|
||||||
is the look up key.
|
|
||||||
Now when the mock object has the
|
|
||||||
<span class="new_code">get()</span> method invoked
|
|
||||||
like this...
|
|
||||||
<pre>
|
|
||||||
$config->get('db_user')
|
|
||||||
</pre>
|
|
||||||
...it will return "admin".
|
|
||||||
It finds this by attempting to match the calling arguments
|
|
||||||
to its list of returns one after another until
|
|
||||||
a complete match is found.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You can set a default argument argument like so...
|
|
||||||
<pre><strong>
|
|
||||||
$config->returns('get', false, array('*'));</strong>
|
|
||||||
</pre>
|
|
||||||
This is not the same as setting the return value without
|
|
||||||
any argument requirements like this...
|
|
||||||
<pre><strong>
|
|
||||||
$config->returns('get', false);</strong>
|
|
||||||
</pre>
|
|
||||||
In the first case it will accept any single argument,
|
|
||||||
but exactly one is required.
|
|
||||||
In the second case any number of arguments will do and
|
|
||||||
it acts as a catchall after all other matches.
|
|
||||||
Note that if we add further single parameter options after
|
|
||||||
the wildcard in the first case, they will be ignored as the wildcard
|
|
||||||
will match first.
|
|
||||||
With complex parameter lists the ordering could be important
|
|
||||||
or else desired matches could be masked by earlier wildcard
|
|
||||||
ones.
|
|
||||||
Declare the most specific matches first if you are not sure.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
There are times when you want a specific reference to be
|
|
||||||
dished out by the mock rather than a copy or object handle.
|
|
||||||
This a rarity to say the least, but you might be simulating
|
|
||||||
a container that can hold primitives such as strings.
|
|
||||||
For example...
|
|
||||||
<pre>
|
|
||||||
class Pad {
|
|
||||||
function Pad() { }
|
|
||||||
function &note($index) { }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
In this case you can set a reference into the mock's
|
|
||||||
return list...
|
|
||||||
<pre>
|
|
||||||
function testTaskReads() {
|
|
||||||
$note = 'Buy books';
|
|
||||||
$pad = new MockPad();
|
|
||||||
$vector-><strong>returnsByReference(</strong>'note', $note, array(3)<strong>)</strong>;
|
|
||||||
$task = new Task($pad);
|
|
||||||
...
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
With this arrangement you know that every time
|
|
||||||
<span class="new_code">$pad->note(3)</span> is
|
|
||||||
called it will return the same <span class="new_code">$note</span> each time,
|
|
||||||
even if it get's modified.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
These three factors, timing, parameters and whether to copy,
|
|
||||||
can be combined orthogonally.
|
|
||||||
For example...
|
|
||||||
<pre>
|
|
||||||
$buy_books = 'Buy books';
|
|
||||||
$write_code = 'Write code';
|
|
||||||
$pad = new MockPad();
|
|
||||||
$vector-><strong>returnsByReferenceAt(0, 'note', $buy_books, array('*', 3));</strong>
|
|
||||||
$vector-><strong>returnsByReferenceAt(1, 'note', $write_code, array('*', 3));</strong>
|
|
||||||
</pre>
|
|
||||||
This will return a reference to <span class="new_code">$buy_books</span> and
|
|
||||||
then to <span class="new_code">$write_code</span>, but only if two parameters
|
|
||||||
were set the second of which must be the integer 3.
|
|
||||||
That should cover most situations.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A final tricky case is one object creating another, known
|
|
||||||
as a factory pattern.
|
|
||||||
Suppose that on a successful query to our imaginary
|
|
||||||
database, a result set is returned as an iterator, with
|
|
||||||
each call to the the iterator's <span class="new_code">next()</span> giving
|
|
||||||
one row until false.
|
|
||||||
This sounds like a simulation nightmare, but in fact it can all
|
|
||||||
be mocked using the mechanics above...
|
|
||||||
<pre>
|
|
||||||
Mock::generate('DatabaseConnection');
|
|
||||||
Mock::generate('ResultIterator');
|
|
||||||
|
|
||||||
class DatabaseTest extends UnitTestCase {
|
|
||||||
|
|
||||||
function testUserFinderReadsResultsFromDatabase() {<strong>
|
|
||||||
$result = new MockResultIterator();
|
|
||||||
$result->returns('next', false);
|
|
||||||
$result->returnsAt(0, 'next', array(1, 'tom'));
|
|
||||||
$result->returnsAt(1, 'next', array(3, 'dick'));
|
|
||||||
$result->returnsAt(2, 'next', array(6, 'harry'));
|
|
||||||
|
|
||||||
$connection = new MockDatabaseConnection();
|
|
||||||
$connection->returns('selectQuery', $result);</strong>
|
|
||||||
|
|
||||||
$finder = new UserFinder(<strong>$connection</strong>);
|
|
||||||
$this->assertIdentical(
|
|
||||||
$finder->findNames(),
|
|
||||||
array('tom', 'dick', 'harry'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Now only if our
|
|
||||||
<span class="new_code">$connection</span> is called with the
|
|
||||||
<span class="new_code">query()</span> method will the
|
|
||||||
<span class="new_code">$result</span> be returned that is
|
|
||||||
itself exhausted after the third call to <span class="new_code">next()</span>.
|
|
||||||
This should be enough
|
|
||||||
information for our <span class="new_code">UserFinder</span> class,
|
|
||||||
the class actually
|
|
||||||
being tested here, to come up with goods.
|
|
||||||
A very precise test and not a real database in sight.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We could refine this test further by insisting that the correct
|
|
||||||
query is sent...
|
|
||||||
<pre>
|
|
||||||
$connection->returns('selectQuery', $result, array(<strong>'select name, id from people'</strong>));
|
|
||||||
</pre>
|
|
||||||
This is actually a bad idea.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We have a <span class="new_code">UserFinder</span> in object land, talking to
|
|
||||||
database tables using a large interface - the whole of SQL.
|
|
||||||
Imagine that we have written a lot of tests that now depend
|
|
||||||
on the exact SQL string passed.
|
|
||||||
These queries could change en masse for all sorts of reasons
|
|
||||||
not related to the specific test.
|
|
||||||
For example the quoting rules could change, a table name could
|
|
||||||
change, a link table added or whatever.
|
|
||||||
This would require the rewriting of every single test any time
|
|
||||||
one of these refactoring is made, yet the intended behaviour has
|
|
||||||
stayed the same.
|
|
||||||
Tests are supposed to help refactoring, not hinder it.
|
|
||||||
I'd certainly like to have a test suite that passes while I change
|
|
||||||
table names.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
As a rule it is best not to mock a fat interface.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
By contrast, here is the round trip test...
|
|
||||||
<pre>
|
|
||||||
class DatabaseTest extends UnitTestCase {<strong>
|
|
||||||
function setUp() { ... }
|
|
||||||
function tearDown() { ... }</strong>
|
|
||||||
|
|
||||||
function testUserFinderReadsResultsFromDatabase() {
|
|
||||||
$finder = new UserFinder(<strong>new DatabaseConnection()</strong>);
|
|
||||||
$finder->add('tom');
|
|
||||||
$finder->add('dick');
|
|
||||||
$finder->add('harry');
|
|
||||||
$this->assertIdentical(
|
|
||||||
$finder->findNames(),
|
|
||||||
array('tom', 'dick', 'harry'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This test is immune to schema changes.
|
|
||||||
It will only fail if you actually break the functionality, which
|
|
||||||
is what you want a test to do.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The catch is those <span class="new_code">setUp()</span> and <span class="new_code">tearDown()</span>
|
|
||||||
methods that we've rather glossed over.
|
|
||||||
They have to clear out the database tables and ensure that the
|
|
||||||
schema is defined correctly.
|
|
||||||
That can be a chunk of extra work, but you usually have this code
|
|
||||||
lying around anyway for deployment purposes.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
One place where you definitely need a mock is simulating failures.
|
|
||||||
Say the database goes down while <span class="new_code">UserFinder</span> is doing
|
|
||||||
it's work.
|
|
||||||
Does <span class="new_code">UserFinder</span> behave well...?
|
|
||||||
<pre>
|
|
||||||
class DatabaseTest extends UnitTestCase {
|
|
||||||
|
|
||||||
function testUserFinder() {
|
|
||||||
$connection = new MockDatabaseConnection();<strong>
|
|
||||||
$connection->throwOn('selectQuery', new TimedOut('Ouch!'));</strong>
|
|
||||||
$alert = new MockAlerts();<strong>
|
|
||||||
$alert->expectOnce('notify', 'Database is busy - please retry');</strong>
|
|
||||||
$finder = new UserFinder($connection, $alert);
|
|
||||||
$this->assertIdentical($finder->findNames(), array());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
We've passed the <span class="new_code">UserFinder</span> an <span class="new_code">$alert</span>
|
|
||||||
object.
|
|
||||||
This is going to do some kind of pretty notifications in the
|
|
||||||
user interface in the event of an error.
|
|
||||||
We'd rather not sprinkle our code with hard wired <span class="new_code">print</span>
|
|
||||||
statements if we can avoid it.
|
|
||||||
Wrapping the means of output means we can use this code anywhere.
|
|
||||||
It also makes testing easier.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To pass this test, the finder has to write a nice user friendly
|
|
||||||
message to <span class="new_code">$alert</span>, rather than propogating the exception.
|
|
||||||
So far, so good.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
How do we get the mock <span class="new_code">DatabaseConnection</span> to throw an exception?
|
|
||||||
We generate the exception using the <span class="new_code">throwOn</span> method
|
|
||||||
on the mock.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Finally, what if the method you want to simulate does not exist yet?
|
|
||||||
If you set a return value on a method that is not there, SimpleTest
|
|
||||||
will throw an error.
|
|
||||||
What if you are using <span class="new_code">__call()</span> to simulate dynamic methods?
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Objects with dynamic interfaces, using <span class="new_code">__call</span>, can
|
|
||||||
be problematic with the current mock objects implementation.
|
|
||||||
You can mock the <span class="new_code">__call()</span> method, but this is ugly.
|
|
||||||
Why should a test know anything about such low level implementation details?
|
|
||||||
It just wants to simulate the call.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The way round this is to add extra methods to the mock when
|
|
||||||
generating it.
|
|
||||||
<pre>
|
|
||||||
<strong>Mock::generate('DatabaseConnection', 'MockDatabaseConnection', array('setOptions'));</strong>
|
|
||||||
</pre>
|
|
||||||
In a large test suite this could cause trouble, as you probably
|
|
||||||
already have a mock version of the class called
|
|
||||||
<span class="new_code">MockDatabaseConnection</span> without the extra methods.
|
|
||||||
The code generator will not generate a mock version of the class if
|
|
||||||
one of the same name already exists.
|
|
||||||
You will confusingly fail to see your method if another definition
|
|
||||||
was run first.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To cope with this, SimpleTest allows you to choose any name for the
|
|
||||||
new class at the same time as you add the extra methods.
|
|
||||||
<pre>
|
|
||||||
Mock::generate('DatabaseConnection', <strong>'MockDatabaseConnectionWithOptions'</strong>, array('setOptions'));
|
|
||||||
</pre>
|
|
||||||
Here the mock will behave as if the <span class="new_code">setOptions()</span>
|
|
||||||
existed in the original class.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Mock objects can only be used within test cases, as upon expectations
|
|
||||||
they send messages straight to the currently running test case.
|
|
||||||
Creating them outside a test case will cause a run time error
|
|
||||||
when an expectation is triggered and there is no running test case
|
|
||||||
for the message to end up.
|
|
||||||
We cover expectations next.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="expectations"></a>Mocks as critics</h2>
|
|
||||||
<p>
|
|
||||||
Although the server stubs approach insulates your tests from
|
|
||||||
real world disruption, it is only half the benefit.
|
|
||||||
You can have the class under test receiving the required
|
|
||||||
messages, but is your new class sending correct ones?
|
|
||||||
Testing this can get messy without a mock objects library.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
By way of example, let's take a simple <span class="new_code">PageController</span>
|
|
||||||
class to handle a credit card payment form...
|
|
||||||
<pre>
|
|
||||||
class PaymentForm extends PageController {
|
|
||||||
function __construct($alert, $payment_gateway) { ... }
|
|
||||||
function makePayment($request) { ... }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This class takes a <span class="new_code">PaymentGateway</span> to actually talk
|
|
||||||
to the bank.
|
|
||||||
It also takes an <span class="new_code">Alert</span> object to handle errors.
|
|
||||||
This class talks to the page or template.
|
|
||||||
It's responsible for painting the error message and highlighting any
|
|
||||||
form fields that are incorrect.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
It might look something like...
|
|
||||||
<pre>
|
|
||||||
class Alert {
|
|
||||||
function warn($warning, $id) {
|
|
||||||
print '<div class="warning">' . $warning . '</div>';
|
|
||||||
print '<style type="text/css">#' . $id . ' { background-color: red }</style>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Our interest is in the <span class="new_code">makePayment()</span> method.
|
|
||||||
If we fail to enter a "CVV2" number (the three digit number
|
|
||||||
on the back of the credit card), we want to show an error rather than
|
|
||||||
try to process the payment.
|
|
||||||
In test form...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
require_once('payment_form.php');
|
|
||||||
Mock::generate('Alert');
|
|
||||||
Mock::generate('PaymentGateway');
|
|
||||||
|
|
||||||
class PaymentFormFailuresShouldBeGraceful extends UnitTestCase {
|
|
||||||
|
|
||||||
function testMissingCvv2CausesAlert() {
|
|
||||||
$alert = new MockAlert();
|
|
||||||
<strong>$alert->expectOnce(
|
|
||||||
'warn',
|
|
||||||
array('Missing three digit security code', 'cvv2'));</strong>
|
|
||||||
$controller = new PaymentForm(<strong>$alert</strong>, new MockPaymentGateway());
|
|
||||||
$controller->makePayment($this->requestWithMissingCvv2());
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestWithMissingCvv2() { ... }
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
The first question you may be asking is, where are the assertions?
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The call to <span class="new_code">expectOnce('warn', array(...))</span> instructs the mock
|
|
||||||
to expect a call to <span class="new_code">warn()</span> before the test ends.
|
|
||||||
When it gets a call to <span class="new_code">warn()</span>, it checks the arguments.
|
|
||||||
If the arguments don't match, then a failure is generated.
|
|
||||||
It also fails if the method is never called at all.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The test above not only asserts that <span class="new_code">warn</span> was called,
|
|
||||||
but that it received the string "Missing three digit security code"
|
|
||||||
and also the tag "cvv2".
|
|
||||||
The equivalent of <span class="new_code">assertIdentical()</span> is applied to both
|
|
||||||
fields when the parameters are compared.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you are not interested in the actual message, and we are not
|
|
||||||
for user interface code that changes often, we can skip that
|
|
||||||
parameter with the "*" operator...
|
|
||||||
<pre>
|
|
||||||
class PaymentFormFailuresShouldBeGraceful extends UnitTestCase {
|
|
||||||
|
|
||||||
function testMissingCvv2CausesAlert() {
|
|
||||||
$alert = new MockAlert();
|
|
||||||
$alert->expectOnce('warn', array(<strong>'*'</strong>, 'cvv2'));
|
|
||||||
$controller = new PaymentForm($alert, new MockPaymentGateway());
|
|
||||||
$controller->makePayment($this->requestWithMissingCvv2());
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestWithMissingCvv2() { ... }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
We can weaken the test further by missing
|
|
||||||
out the parameters array...
|
|
||||||
<pre>
|
|
||||||
function testMissingCvv2CausesAlert() {
|
|
||||||
$alert = new MockAlert();
|
|
||||||
<strong>$alert->expectOnce('warn');</strong>
|
|
||||||
$controller = new PaymentForm($alert, new MockPaymentGateway());
|
|
||||||
$controller->makePayment($this->requestWithMissingCvv2());
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
This will only test that the method is called,
|
|
||||||
which is a bit drastic in this case.
|
|
||||||
Later on, we'll see how we can weaken the expectations more precisely.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Tests without assertions can be both compact and very expressive.
|
|
||||||
Because we intercept the call on the way into an object, here of
|
|
||||||
the <span class="new_code">Alert</span> class, we avoid having to assert its state
|
|
||||||
afterwards.
|
|
||||||
This not only avoids the assertions in the tests, but also having
|
|
||||||
to add extra test only accessors to the original code.
|
|
||||||
If you catch yourself adding such accessors, called "state based testing",
|
|
||||||
it's probably time to consider using mocks in the tests.
|
|
||||||
This is called "behaviour based testing", and is normally superior.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Let's add another test.
|
|
||||||
Let's make sure that we don't even attempt a payment without a CVV2...
|
|
||||||
<pre>
|
|
||||||
class PaymentFormFailuresShouldBeGraceful extends UnitTestCase {
|
|
||||||
|
|
||||||
function testMissingCvv2CausesAlert() { ... }
|
|
||||||
|
|
||||||
function testNoPaymentAttemptedWithMissingCvv2() {
|
|
||||||
$payment_gateway = new MockPaymentGateway();
|
|
||||||
<strong>$payment_gateway->expectNever('pay');</strong>
|
|
||||||
$controller = new PaymentForm(new MockAlert(), $payment_gateway);
|
|
||||||
$controller->makePayment($this->requestWithMissingCvv2());
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Asserting a negative can be very hard in tests, but
|
|
||||||
<span class="new_code">expectNever()</span> makes it easy.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="new_code">expectOnce()</span> and <span class="new_code">expectNever()</span> are
|
|
||||||
sufficient for most tests, but
|
|
||||||
occasionally you want to test multiple events.
|
|
||||||
Normally for usability purposes we want all missing fields
|
|
||||||
in the form to light up, not just the first one.
|
|
||||||
This means that we should get multiple calls to
|
|
||||||
<span class="new_code">Alert::warn()</span>, not just one...
|
|
||||||
<pre>
|
|
||||||
function testAllRequiredFieldsHighlightedOnEmptyRequest() {
|
|
||||||
$alert = new MockAlert();<strong>
|
|
||||||
$alert->expectAt(0, 'warn', array('*', 'cc_number'));
|
|
||||||
$alert->expectAt(1, 'warn', array('*', 'expiry'));
|
|
||||||
$alert->expectAt(2, 'warn', array('*', 'cvv2'));
|
|
||||||
$alert->expectAt(3, 'warn', array('*', 'card_holder'));
|
|
||||||
$alert->expectAt(4, 'warn', array('*', 'address'));
|
|
||||||
$alert->expectAt(5, 'warn', array('*', 'postcode'));
|
|
||||||
$alert->expectAt(6, 'warn', array('*', 'country'));
|
|
||||||
$alert->expectCallCount('warn', 7);</strong>
|
|
||||||
$controller = new PaymentForm($alert, new MockPaymentGateway());
|
|
||||||
$controller->makePayment($this->requestWithMissingCvv2());
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The counter in <span class="new_code">expectAt()</span> is the number of times
|
|
||||||
the method has been called already.
|
|
||||||
Here we are asserting that every field will be highlighted.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Note that we are forced to assert the order too.
|
|
||||||
SimpleTest does not yet have a way to avoid this, but
|
|
||||||
this will be fixed in future versions.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here is the full list of expectations you can set on a mock object
|
|
||||||
in <a href="http://simpletest.org/">SimpleTest</a>.
|
|
||||||
As with the assertions, these methods take an optional failure message.
|
|
||||||
<table>
|
|
||||||
<thead><tr>
|
|
||||||
<th>Expectation</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expect($method, $args)</span></td>
|
|
||||||
<td>Arguments must match if called</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectAt($timing, $method, $args)</span></td>
|
|
||||||
<td>Arguments must match when called on the <span class="new_code">$timing</span>'th time</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectCallCount($method, $count)</span></td>
|
|
||||||
<td>The method must be called exactly this many times</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectMaximumCallCount($method, $count)</span></td>
|
|
||||||
<td>Call this method no more than <span class="new_code">$count</span> times</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectMinimumCallCount($method, $count)</span></td>
|
|
||||||
<td>Must be called at least <span class="new_code">$count</span> times</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectNever($method)</span></td>
|
|
||||||
<td>Must never be called</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectOnce($method, $args)</span></td>
|
|
||||||
<td>Must be called once and with the expected arguments if supplied</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><span class="new_code">expectAtLeastOnce($method, $args)</span></td>
|
|
||||||
<td>Must be called at least once, and always with any expected arguments</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
Where the parameters are...
|
|
||||||
<dl>
|
|
||||||
<dt class="new_code">$method</dt>
|
|
||||||
<dd>The method name, as a string, to apply the condition to.</dd>
|
|
||||||
<dt class="new_code">$args</dt>
|
|
||||||
<dd>
|
|
||||||
The arguments as a list. Wildcards can be included in the same
|
|
||||||
manner as for <span class="new_code">setReturn()</span>.
|
|
||||||
This argument is optional for <span class="new_code">expectOnce()</span>
|
|
||||||
and <span class="new_code">expectAtLeastOnce()</span>.
|
|
||||||
</dd>
|
|
||||||
<dt class="new_code">$timing</dt>
|
|
||||||
<dd>
|
|
||||||
The only point in time to test the condition.
|
|
||||||
The first call starts at zero and the count is for
|
|
||||||
each method independently.
|
|
||||||
</dd>
|
|
||||||
<dt class="new_code">$count</dt>
|
|
||||||
<dd>The number of calls expected.</dd>
|
|
||||||
</dl>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you have just one call in your test, make sure you're using
|
|
||||||
<span class="new_code">expectOnce</span>.<br>
|
|
||||||
Using <span class="new_code">$mocked->expectAt(0, 'method', 'args);</span>
|
|
||||||
on its own will allow the method to never be called.
|
|
||||||
Checking the arguments and the overall call count
|
|
||||||
are currently independant.
|
|
||||||
Add an <span class="new_code">expectCallCount()</span> expectation when you
|
|
||||||
are using <span class="new_code">expectAt()</span> unless zero calls is allowed.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Like the assertions within test cases, all of the expectations
|
|
||||||
can take a message override as an extra parameter.
|
|
||||||
Also the original failure message can be embedded in the output
|
|
||||||
as "%s".
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
The original
|
|
||||||
<a href="http://www.mockobjects.com/">Mock objects</a> paper.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest home page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Mock objects</span>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,487 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>
|
|
||||||
Overview and feature list for the SimpleTest PHP unit tester and web tester
|
|
||||||
</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Overview</span>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Overview of SimpleTest</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="#summary">Quick summary</a>
|
|
||||||
of the SimpleTest tool for PHP.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#features">List of features</a>,
|
|
||||||
both current ones and those planned.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="summary"></a>What is SimpleTest?</h2>
|
|
||||||
<p>
|
|
||||||
The heart of SimpleTest is a testing framework built around
|
|
||||||
test case classes.
|
|
||||||
These are written as extensions of base test case classes,
|
|
||||||
each extended with methods that actually contain test code.
|
|
||||||
Each test method of a test case class is written to invoke
|
|
||||||
various assertions that the developer expects to be true such as
|
|
||||||
<span class="new_code">assertEqual()</span>.
|
|
||||||
If the expectation is correct, then a successful result is
|
|
||||||
dispatched to the observing test reporter, but any failure
|
|
||||||
or unexpected exception triggers an alert and a description
|
|
||||||
of the mismatch.
|
|
||||||
These test case declarations are transformed into executable
|
|
||||||
test scripts by including a SimpleTest aurorun.php file.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
These documents apply to SimpleTest version 1.1, although we
|
|
||||||
try hard to maintain compatibility between versions.
|
|
||||||
If you get a test failure after an upgrade, check out the
|
|
||||||
file "HELP_MY_TESTS_DONT_WORK_ANYMORE" in the
|
|
||||||
simpletest directory to see if a feature you are using
|
|
||||||
has since been deprecated and later removed.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A <a href="unit_test_documentation.html">test case</a> looks like this...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
class <strong>CanAddUp</strong> extends UnitTestCase {<strong>
|
|
||||||
function testOneAndOneMakesTwo() {
|
|
||||||
$this->assertEqual(1 + 1, 2);
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
Tests are grouped into test cases, which are just
|
|
||||||
PHP classes that extend <span class="new_code">UnitTestCase</span>
|
|
||||||
or <span class="new_code">WebTestCase</span>.
|
|
||||||
The tests themselves are just normal methods that start
|
|
||||||
their name with the letters "test".
|
|
||||||
You can have as many test cases as you want in a test
|
|
||||||
script and each test case can have as many test methods
|
|
||||||
as it wants too.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This test script is immediately runnable.
|
|
||||||
You just invoke it on the command line like so...
|
|
||||||
<pre class="shell">
|
|
||||||
php adding_test.php
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
When run on the command line you should see something like...
|
|
||||||
<pre class="shell">
|
|
||||||
adding_test.php
|
|
||||||
OK
|
|
||||||
Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you place it on a web server and point your
|
|
||||||
web browser at it...
|
|
||||||
<div class="demo">
|
|
||||||
<h1>adding_test.php</h1>
|
|
||||||
<div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
|
|
||||||
<strong>6</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Of course this is a silly example.
|
|
||||||
A more realistic example might be...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
require_once('log.php');
|
|
||||||
|
|
||||||
class <strong>TestOfLogging</strong> extends UnitTestCase {
|
|
||||||
function testWillCreateLogFileOnFirstMessage() {
|
|
||||||
$log = new Log('my.log');
|
|
||||||
$this->assertFalse(file_exists('my.log'));
|
|
||||||
$log->message('Hello');
|
|
||||||
$this->assertTrue(file_exists('my.log'));
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This tool is designed for the developer.
|
|
||||||
The target audience of this tool is anyone developing a small
|
|
||||||
to medium PHP application, including developers new to
|
|
||||||
unit and web regression testing.
|
|
||||||
The core principles are ease of use first, with extendibility and
|
|
||||||
essential features.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Tests are written in the PHP language itself more or less
|
|
||||||
as the application itself is built.
|
|
||||||
The advantage of using PHP as the testing language is that
|
|
||||||
there are no new languages to learn, testing can start straight away,
|
|
||||||
and the developer can test any part of the code.
|
|
||||||
Basically, all parts that can be accessed by the application code can also be
|
|
||||||
accessed by the test code when they are in the same programming language.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The simplest type of test case is the
|
|
||||||
<a href="unit_tester_documentation.html">UnitTestCase</a>.
|
|
||||||
This class of test case includes standard tests for equality,
|
|
||||||
references and pattern matching.
|
|
||||||
All these test the typical expectations of what you would
|
|
||||||
expect the result of a function or method to be.
|
|
||||||
This is by far the most common type of test in the daily
|
|
||||||
routine of development, making up about 95% of test cases.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The top level task of a web application though is not to
|
|
||||||
produce correct output from its methods and objects, but
|
|
||||||
to generate web pages.
|
|
||||||
The <a href="web_tester_documentation.html">WebTestCase</a> class tests web
|
|
||||||
pages.
|
|
||||||
It simulates a web browser requesting a page, complete with
|
|
||||||
cookies, proxies, secure connections, authentication, forms, frames and most
|
|
||||||
navigation elements.
|
|
||||||
With this type of test case, the developer can assert that
|
|
||||||
information is present in the page and that forms and
|
|
||||||
sessions are handled correctly.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A <a href="web_tester_documentation.html">WebTestCase</a> looks like this...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
require_once('simpletest/web_tester.php');
|
|
||||||
|
|
||||||
class <strong>MySiteTest</strong> extends WebTestCase {
|
|
||||||
<strong>
|
|
||||||
function testHomePageHasContactDetailsLink() {
|
|
||||||
$this->get('http://www.my-site.com/index.php');
|
|
||||||
$this->assertTitle('My Home Page');
|
|
||||||
$this->clickLink('Contact');
|
|
||||||
$this->assertTitle('Contact me');
|
|
||||||
$this->assertText('/Email me at/');
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="features"></a>Feature list</h2>
|
|
||||||
<p>
|
|
||||||
The following is a very rough outline of past and future features
|
|
||||||
and their expected point of release.
|
|
||||||
I am afraid it is liable to change without warning, as meeting the
|
|
||||||
milestones rather depends on time available.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Green stuff has been coded, but not necessarily released yet.
|
|
||||||
If you have a pressing need for a green but unreleased feature
|
|
||||||
then you should check-out the code from Sourceforge SVN directly.
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Feature</th>
|
|
||||||
<th>Description</th>
|
|
||||||
<th>Release</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>Unit test case</td>
|
|
||||||
<td>Core test case class and assertions</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Html display</td>
|
|
||||||
<td>Simplest possible display</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Autoloading of test cases</td>
|
|
||||||
<td>
|
|
||||||
Reading a file with test cases and loading them into a
|
|
||||||
group test automatically
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Mock objects</td>
|
|
||||||
<td>
|
|
||||||
Objects capable of simulating other objects removing
|
|
||||||
test dependencies
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Web test case</td>
|
|
||||||
<td>Allows link following and title tag matching</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Partial mocks</td>
|
|
||||||
<td>
|
|
||||||
Mocking parts of a class for testing less than a class
|
|
||||||
or for complex simulations
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Web cookie handling</td>
|
|
||||||
<td>Correct handling of cookies when fetching pages</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Following redirects</td>
|
|
||||||
<td>Page fetching automatically follows 300 redirects</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Form parsing</td>
|
|
||||||
<td>Ability to submit simple forms and read default form values</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Command line interface</td>
|
|
||||||
<td>Test display without the need of a web browser</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Exposure of expectation classes</td>
|
|
||||||
<td>Can create precise tests with mocks as well as test cases</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>XML output and parsing</td>
|
|
||||||
<td>
|
|
||||||
Allows multi host testing and the integration of acceptance
|
|
||||||
testing extensions
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Browser component</td>
|
|
||||||
<td>
|
|
||||||
Exposure of lower level web browser interface for more
|
|
||||||
detailed test cases
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>HTTP authentication</td>
|
|
||||||
<td>
|
|
||||||
Fetching protected web pages with basic authentication
|
|
||||||
only
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>SSL support</td>
|
|
||||||
<td>Can connect to https: pages</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Proxy support</td>
|
|
||||||
<td>Can connect via. common proxies</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Frames support</td>
|
|
||||||
<td>Handling of frames in web test cases</td>
|
|
||||||
<td style="color: green;">1.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>File upload testing</td>
|
|
||||||
<td>Can simulate the input type file tag</td>
|
|
||||||
<td style="color: green;">1.0.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Mocking interfaces</td>
|
|
||||||
<td>
|
|
||||||
Can generate mock objects to interfaces as well as classes
|
|
||||||
and class interfaces are carried for type hints
|
|
||||||
</td>
|
|
||||||
<td style="color: green;">1.0.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Testing exceptions</td>
|
|
||||||
<td>Similar to testing PHP errors</td>
|
|
||||||
<td style="color: green;">1.0.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>HTML label support</td>
|
|
||||||
<td>Can access all controls using the visual label</td>
|
|
||||||
<td style="color: green;">1.0.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Base tag support</td>
|
|
||||||
<td>Respects page base tag when clicking</td>
|
|
||||||
<td style="color: green;">1.0.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PHP 5 E_STRICT compliant</td>
|
|
||||||
<td>PHP 5 only version that works with the E_STRICT error level</td>
|
|
||||||
<td style="color: green;">1.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Alternate HTML parsers</td>
|
|
||||||
<td>Can detect compiled parsers for performance improvements</td>
|
|
||||||
<td style="color: green;">1.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>REST support</td>
|
|
||||||
<td>Support for REST verbs as put(), delete(), etc.</td>
|
|
||||||
<td style="color: green;">1.1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>BDD style fixtures</td>
|
|
||||||
<td>Can import fixtures using a mixin like given() method</td>
|
|
||||||
<td style="color: red;">1.5</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Plug-in architecture</td>
|
|
||||||
<td>Automatic import of extensions including command line options</td>
|
|
||||||
<td style="color: red;">1.5</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Reporting machinery enhancements</td>
|
|
||||||
<td>Improved message passing for better cooperation with IDEs</td>
|
|
||||||
<td style="color: red;">1.5</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Fluent mock interface</td>
|
|
||||||
<td>More flexible and concise mock objects</td>
|
|
||||||
<td style="color: red;">1.6</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Localisation</td>
|
|
||||||
<td>Messages abstracted and code generated as well as UTF support</td>
|
|
||||||
<td style="color: red;">1.6</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>CSS selectors</td>
|
|
||||||
<td>HTML content can be examined using CSS selectors</td>
|
|
||||||
<td style="color: red;">1.7</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>HTML table assertions</td>
|
|
||||||
<td>Can match HTML or other table elements to expectations</td>
|
|
||||||
<td style="color: red;">1.7</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Unified acceptance testing model</td>
|
|
||||||
<td>Content searchable through selectors combined with expectations</td>
|
|
||||||
<td style="color: red;">1.7</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>DatabaseTestCase</td>
|
|
||||||
<td>SQL selectors and DB drivers</td>
|
|
||||||
<td style="color: red;">1.7</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>IFrame support</td>
|
|
||||||
<td>Reads IFrame content that can be refreshed</td>
|
|
||||||
<td style="color: red;">1.8</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Integrated Selenium support</td>
|
|
||||||
<td>Easy to use built in Selenium driver and tutorial or similar browser automation</td>
|
|
||||||
<td style="color: red;">1.9</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Code coverage</td>
|
|
||||||
<td>Reports using the bundled tool when using XDebug</td>
|
|
||||||
<td style="color: red;">1.9</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Deprecation of old methods</td>
|
|
||||||
<td>Simpler interface for SimpleTest2</td>
|
|
||||||
<td style="color: red;">2.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Javascript suport</td>
|
|
||||||
<td>Use of PECL module to add Javascript to the native browser</td>
|
|
||||||
<td style="color: red;">3.0</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
PHP 5 migration is complete, which means that only PHP 5.0.3+
|
|
||||||
will be supported in SimpleTest version 1.1+.
|
|
||||||
Earlier versions of SimpleTest are compatible with PHP 4.2 up to
|
|
||||||
PHP 5 (non E_STRICT).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="unit_test_documentation.html">Documentation for SimpleTest</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="http://www.lastcraft.com/first_test_tutorial.php">How to write PHP test cases</a>
|
|
||||||
is a fairly advanced tutorial.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="http://simpletest.org/api/">SimpleTest API</a> from phpdoc.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Overview</span>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,457 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest for PHP partial mocks documentation</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Partial mocks</span>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Partial mock objects documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="#inject">The mock injection problem</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Moving creation to a <a href="#creation">protected factory</a> method.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#partial">Partial mocks</a> generate subclasses.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Partial mocks <a href="#less">test less than a class</a>.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A partial mock is simply a pattern to alleviate a specific problem
|
|
||||||
in testing with mock objects,
|
|
||||||
that of getting mock objects into tight corners.
|
|
||||||
It's quite a limited tool and possibly not even a good idea.
|
|
||||||
It is included with SimpleTest because I have found it useful
|
|
||||||
on more than one occasion and has saved a lot of work at that point.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="inject"></a>The mock injection problem</h2>
|
|
||||||
<p>
|
|
||||||
When one object uses another it is very simple to just pass a mock
|
|
||||||
version in already set up with its expectations.
|
|
||||||
Things are rather tricker if one object creates another and the
|
|
||||||
creator is the one you want to test.
|
|
||||||
This means that the created object should be mocked, but we can
|
|
||||||
hardly tell our class under test to create a mock instead.
|
|
||||||
The tested class doesn't even know it is running inside a test
|
|
||||||
after all.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For example, suppose we are building a telnet client and it
|
|
||||||
needs to create a network socket to pass its messages.
|
|
||||||
The connection method might look something like...
|
|
||||||
<pre>
|
|
||||||
<strong><?php
|
|
||||||
require_once('socket.php');
|
|
||||||
|
|
||||||
class Telnet {
|
|
||||||
...
|
|
||||||
function connect($ip, $port, $username, $password) {
|
|
||||||
$socket = new Socket($ip, $port);
|
|
||||||
$socket->read( ... );
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?></strong>
|
|
||||||
</pre>
|
|
||||||
We would really like to have a mock object version of the socket
|
|
||||||
here, what can we do?
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The first solution is to pass the socket in as a parameter,
|
|
||||||
forcing the creation up a level.
|
|
||||||
Having the client handle this is actually a very good approach
|
|
||||||
if you can manage it and should lead to factoring the creation from
|
|
||||||
the doing.
|
|
||||||
In fact, this is one way in which testing with mock objects actually
|
|
||||||
forces you to code more tightly focused solutions.
|
|
||||||
They improve your programming.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here this would be...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('socket.php');
|
|
||||||
|
|
||||||
class Telnet {
|
|
||||||
...
|
|
||||||
<strong>function connect($socket, $username, $password) {
|
|
||||||
$socket->read( ... );
|
|
||||||
...
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This means that the test code is typical for a test involving
|
|
||||||
mock objects.
|
|
||||||
<pre>
|
|
||||||
class TelnetTest extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnection() {<strong>
|
|
||||||
$socket = new MockSocket();
|
|
||||||
...
|
|
||||||
$telnet = new Telnet();
|
|
||||||
$telnet->connect($socket, 'Me', 'Secret');
|
|
||||||
...</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
It is pretty obvious though that one level is all you can go.
|
|
||||||
You would hardly want your top level application creating
|
|
||||||
every low level file, socket and database connection ever
|
|
||||||
needed.
|
|
||||||
It wouldn't know the constructor parameters anyway.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The next simplest compromise is to have the created object passed
|
|
||||||
in as an optional parameter...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('socket.php');
|
|
||||||
|
|
||||||
class Telnet {
|
|
||||||
...<strong>
|
|
||||||
function connect($ip, $port, $username, $password, $socket = false) {
|
|
||||||
if (! $socket) {
|
|
||||||
$socket = new Socket($ip, $port);
|
|
||||||
}
|
|
||||||
$socket->read( ... );</strong>
|
|
||||||
...
|
|
||||||
return $socket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
For a quick solution this is usually good enough.
|
|
||||||
The test now looks almost the same as if the parameter
|
|
||||||
was formally passed...
|
|
||||||
<pre>
|
|
||||||
class TelnetTest extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnection() {<strong>
|
|
||||||
$socket = new MockSocket();
|
|
||||||
...
|
|
||||||
$telnet = new Telnet();
|
|
||||||
$telnet->connect('127.0.0.1', 21, 'Me', 'Secret', $socket);
|
|
||||||
...</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The problem with this approach is its untidiness.
|
|
||||||
There is test code in the main class and parameters passed
|
|
||||||
in the test case that are never used.
|
|
||||||
This is a quick and dirty approach, but nevertheless effective
|
|
||||||
in most situations.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The next method is to pass in a factory object to do the creation...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('socket.php');
|
|
||||||
|
|
||||||
class Telnet {<strong>
|
|
||||||
function Telnet($network) {
|
|
||||||
$this->_network = $network;
|
|
||||||
}</strong>
|
|
||||||
...
|
|
||||||
function connect($ip, $port, $username, $password) {<strong>
|
|
||||||
$socket = $this->_network->createSocket($ip, $port);
|
|
||||||
$socket->read( ... );</strong>
|
|
||||||
...
|
|
||||||
return $socket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This is probably the most highly factored answer as creation
|
|
||||||
is now moved into a small specialist class.
|
|
||||||
The networking factory can now be tested separately, but mocked
|
|
||||||
easily when we are testing the telnet class...
|
|
||||||
<pre>
|
|
||||||
class TelnetTest extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnection() {<strong>
|
|
||||||
$socket = new MockSocket();
|
|
||||||
...
|
|
||||||
$network = new MockNetwork();
|
|
||||||
$network->returnsByReference('createSocket', $socket);
|
|
||||||
$telnet = new Telnet($network);
|
|
||||||
$telnet->connect('127.0.0.1', 21, 'Me', 'Secret');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The downside is that we are adding a lot more classes to the
|
|
||||||
library.
|
|
||||||
Also we are passing a lot of factories around which will
|
|
||||||
make the code a little less intuitive.
|
|
||||||
The most flexible solution, but the most complex.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Well techniques like "Dependency Injection" tackle the problem of
|
|
||||||
instantiating a lot of constructor parameters.
|
|
||||||
Unfortunately knowledge of this pattern is not widespread, and if you
|
|
||||||
are trying to get older code to work, rearchitecting the whole
|
|
||||||
application is not really an option.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Is there a middle ground?
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="creation"></a>Protected factory method</h2>
|
|
||||||
<p>
|
|
||||||
There is a way we can circumvent the problem without creating
|
|
||||||
any new application classes, but it involves creating a subclass
|
|
||||||
when we do the actual testing.
|
|
||||||
Firstly we move the socket creation into its own method...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('socket.php');
|
|
||||||
|
|
||||||
class Telnet {
|
|
||||||
...
|
|
||||||
function connect($ip, $port, $username, $password) {
|
|
||||||
<strong>$socket = $this->createSocket($ip, $port);</strong>
|
|
||||||
$socket->read( ... );
|
|
||||||
...
|
|
||||||
}<strong>
|
|
||||||
|
|
||||||
protected function createSocket($ip, $port) {
|
|
||||||
return new Socket($ip, $port);
|
|
||||||
}</strong>
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This is a pretty safe step even for very tangled legacy code.
|
|
||||||
This is the only change we make to the application.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For the test case we have to create a subclass so that
|
|
||||||
we can intercept the socket creation...
|
|
||||||
<pre>
|
|
||||||
<strong>class TelnetTestVersion extends Telnet {
|
|
||||||
var $mock;
|
|
||||||
|
|
||||||
function TelnetTestVersion($mock) {
|
|
||||||
$this->mock = $mock;
|
|
||||||
$this->Telnet();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function createSocket() {
|
|
||||||
return $this->mock;
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
Here I have passed the mock in the constructor, but a
|
|
||||||
setter would have done just as well.
|
|
||||||
Note that the mock was set into the object variable
|
|
||||||
before the constructor was chained.
|
|
||||||
This is necessary in case the constructor calls
|
|
||||||
<span class="new_code">connect()</span>.
|
|
||||||
Otherwise it could get a null value from
|
|
||||||
<span class="new_code">createSocket()</span>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
After the completion of all of this extra work the
|
|
||||||
actual test case is fairly easy.
|
|
||||||
We just test our new class instead...
|
|
||||||
<pre>
|
|
||||||
class TelnetTest extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnection() {<strong>
|
|
||||||
$socket = new MockSocket();
|
|
||||||
...
|
|
||||||
$telnet = new TelnetTestVersion($socket);
|
|
||||||
$telnet->connect('127.0.0.1', 21, 'Me', 'Secret');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The new class is very simple of course.
|
|
||||||
It just sets up a return value, rather like a mock.
|
|
||||||
It would be nice if it also checked the incoming parameters
|
|
||||||
as well.
|
|
||||||
Just like a mock.
|
|
||||||
It seems we are likely to do this often, can
|
|
||||||
we automate the subclass creation?
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="partial"></a>A partial mock</h2>
|
|
||||||
<p>
|
|
||||||
Of course the answer is "yes" or I would have stopped writing
|
|
||||||
this by now!
|
|
||||||
The previous test case was a lot of work, but we can
|
|
||||||
generate the subclass using a similar approach to the mock objects.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here is the partial mock version of the test...
|
|
||||||
<pre>
|
|
||||||
<strong>Mock::generatePartial(
|
|
||||||
'Telnet',
|
|
||||||
'TelnetTestVersion',
|
|
||||||
array('createSocket'));</strong>
|
|
||||||
|
|
||||||
class TelnetTest extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnection() {<strong>
|
|
||||||
$socket = new MockSocket();
|
|
||||||
...
|
|
||||||
$telnet = new TelnetTestVersion();
|
|
||||||
$telnet->setReturnReference('createSocket', $socket);
|
|
||||||
$telnet->Telnet();
|
|
||||||
$telnet->connect('127.0.0.1', 21, 'Me', 'Secret');</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
The partial mock is a subclass of the original with
|
|
||||||
selected methods "knocked out" with test
|
|
||||||
versions.
|
|
||||||
The <span class="new_code">generatePartial()</span> call
|
|
||||||
takes three parameters: the class to be subclassed,
|
|
||||||
the new test class name and a list of methods to mock.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Instantiating the resulting objects is slightly tricky.
|
|
||||||
The only constructor parameter of a partial mock is
|
|
||||||
the unit tester reference.
|
|
||||||
As with the normal mock objects this is needed for sending
|
|
||||||
test results in response to checked expectations.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The original constructor is not run yet.
|
|
||||||
This is necessary in case the constructor is going to
|
|
||||||
make use of the as yet unset mocked methods.
|
|
||||||
We set any return values at this point and then run the
|
|
||||||
constructor with its normal parameters.
|
|
||||||
This three step construction of "new", followed
|
|
||||||
by setting up the methods, followed by running the constructor
|
|
||||||
proper is what distinguishes the partial mock code.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Apart from construction, all of the mocked methods have
|
|
||||||
the same features as mock objects and all of the unmocked
|
|
||||||
methods behave as before.
|
|
||||||
We can set expectations very easily...
|
|
||||||
<pre>
|
|
||||||
class TelnetTest extends UnitTestCase {
|
|
||||||
...
|
|
||||||
function testConnection() {
|
|
||||||
$socket = new MockSocket();
|
|
||||||
...
|
|
||||||
$telnet = new TelnetTestVersion();
|
|
||||||
$telnet->setReturnReference('createSocket', $socket);
|
|
||||||
<strong>$telnet->expectOnce('createSocket', array('127.0.0.1', 21));</strong>
|
|
||||||
$telnet->Telnet();
|
|
||||||
$telnet->connect('127.0.0.1', 21, 'Me', 'Secret');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Partial mocks are not used often.
|
|
||||||
I consider them transitory.
|
|
||||||
Useful while refactoring, but once the application has
|
|
||||||
all of it's dependencies nicely separated then the
|
|
||||||
partial mocks can wither away.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="less"></a>Testing less than a class</h2>
|
|
||||||
<p>
|
|
||||||
The mocked out methods don't have to be factory methods,
|
|
||||||
they could be any sort of method.
|
|
||||||
In this way partial mocks allow us to take control of any part of
|
|
||||||
a class except the constructor.
|
|
||||||
We could even go as far as to mock every method
|
|
||||||
except one we actually want to test.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This last situation is all rather hypothetical, as I've hardly
|
|
||||||
tried it.
|
|
||||||
I am a little worried that
|
|
||||||
forcing object granularity may be better for the code quality.
|
|
||||||
I personally use partial mocks as a way of overriding creation
|
|
||||||
or for occasional testing of the TemplateMethod pattern.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
It's all going to come down to the coding standards of your
|
|
||||||
project to decide if you allow test mechanisms like this.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="http://simpletest.org/api/">Full API for SimpleTest</a>
|
|
||||||
from the PHPDoc.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The protected factory is described in
|
|
||||||
<a href="http://www-106.ibm.com/developerworks/java/library/j-mocktest.html">this paper from IBM</a>.
|
|
||||||
This is the only formal comment I have seen on this problem.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Partial mocks</span>
|
|
||||||
|
|
|
||||||
<a href="reporter_documentation.html">Reporting</a>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,616 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<title>SimpleTest for PHP test runner and display documentation</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Reporting</span>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<h1>Test reporter documentation</h1>
|
|
||||||
This page...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Displaying <a href="#html">results in HTML</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Displaying and <a href="#other">reporting results</a>
|
|
||||||
in other formats
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Using <a href="#cli">SimpleTest from the command line</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#xml">Using XML</a> for remote testing
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="content">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
SimpleTest pretty much follows the MVC-ish pattern
|
|
||||||
(Model-View-Controller).
|
|
||||||
The reporter classes are the view and the model is your
|
|
||||||
test cases and their hiearchy.
|
|
||||||
The controller is mostly hidden from the user of
|
|
||||||
SimpleTest unless you want to change how the test cases
|
|
||||||
are actually run, in which case it is possible to
|
|
||||||
override the runner objects from within the test case.
|
|
||||||
As usual with MVC, the controller is mostly undefined
|
|
||||||
and there are other places to control the test run.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="html"></a>Reporting results in HTML</h2>
|
|
||||||
<p>
|
|
||||||
The default HTML display is minimal in the extreme.
|
|
||||||
It reports success and failure with the conventional red and
|
|
||||||
green bars and shows a breadcrumb trail of test groups
|
|
||||||
for every failed assertion.
|
|
||||||
Here's a fail...
|
|
||||||
<div class="demo">
|
|
||||||
<h1>File test</h1>
|
|
||||||
<span class="fail">Fail</span>: createnewfile->True assertion failed.<br>
|
|
||||||
<div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
|
|
||||||
<strong>0</strong> passes, <strong>1</strong> fails and <strong>0</strong> exceptions.</div>
|
|
||||||
</div>
|
|
||||||
And here all tests passed...
|
|
||||||
<div class="demo">
|
|
||||||
<h1>File test</h1>
|
|
||||||
<div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
|
|
||||||
<strong>1</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
|
|
||||||
</div>
|
|
||||||
The good news is that there are several points in the display
|
|
||||||
hiearchy for subclassing.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For web page based displays there is the
|
|
||||||
<span class="new_code">HtmlReporter</span> class with the following
|
|
||||||
signature...
|
|
||||||
<pre>
|
|
||||||
class HtmlReporter extends SimpleReporter {
|
|
||||||
public __construct($encoding) { ... }
|
|
||||||
public makeDry(boolean $is_dry) { ... }
|
|
||||||
public void paintHeader(string $test_name) { ... }
|
|
||||||
public void sendNoCacheHeaders() { ... }
|
|
||||||
public void paintFooter(string $test_name) { ... }
|
|
||||||
public void paintGroupStart(string $test_name, integer $size) { ... }
|
|
||||||
public void paintGroupEnd(string $test_name) { ... }
|
|
||||||
public void paintCaseStart(string $test_name) { ... }
|
|
||||||
public void paintCaseEnd(string $test_name) { ... }
|
|
||||||
public void paintMethodStart(string $test_name) { ... }
|
|
||||||
public void paintMethodEnd(string $test_name) { ... }
|
|
||||||
public void paintFail(string $message) { ... }
|
|
||||||
public void paintPass(string $message) { ... }
|
|
||||||
public void paintError(string $message) { ... }
|
|
||||||
public void paintException(string $message) { ... }
|
|
||||||
public void paintMessage(string $message) { ... }
|
|
||||||
public void paintFormattedMessage(string $message) { ... }
|
|
||||||
protected string getCss() { ... }
|
|
||||||
public array getTestList() { ... }
|
|
||||||
public integer getPassCount() { ... }
|
|
||||||
public integer getFailCount() { ... }
|
|
||||||
public integer getExceptionCount() { ... }
|
|
||||||
public integer getTestCaseCount() { ... }
|
|
||||||
public integer getTestCaseProgress() { ... }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
Here is what some of these methods mean. First the display methods
|
|
||||||
that you will probably want to override...
|
|
||||||
<ul class="api">
|
|
||||||
<li>
|
|
||||||
<span class="new_code">HtmlReporter(string $encoding)</span><br>
|
|
||||||
is the constructor.
|
|
||||||
Note that the unit test sets up the link to the display
|
|
||||||
rather than the other way around.
|
|
||||||
The display is a mostly passive receiver of test events.
|
|
||||||
This allows easy adaption of the display for other test
|
|
||||||
systems beside unit tests, such as monitoring servers.
|
|
||||||
The encoding is the character encoding you wish to
|
|
||||||
display the test output in.
|
|
||||||
In order to correctly render debug output when
|
|
||||||
using the web tester, this should match the encoding
|
|
||||||
of the site you are trying to test.
|
|
||||||
The available character set strings are described in
|
|
||||||
the PHP <a href="http://www.php.net/manual/en/function.htmlentities.php">html_entities()</a>
|
|
||||||
function.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">void paintHeader(string $test_name)</span><br>
|
|
||||||
is called once at the very start of the test when the first
|
|
||||||
start event arrives.
|
|
||||||
The first start event is usually delivered by the top level group
|
|
||||||
test and so this is where <span class="new_code">$test_name</span>
|
|
||||||
comes from.
|
|
||||||
It paints the page title, CSS, body tag, etc.
|
|
||||||
It returns nothing (<span class="new_code">void</span>).
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">void paintFooter(string $test_name)</span><br>
|
|
||||||
Called at the very end of the test to close any tags opened
|
|
||||||
by the page header.
|
|
||||||
By default it also displays the red/green bar and the final
|
|
||||||
count of results.
|
|
||||||
Actually the end of the test happens when a test end event
|
|
||||||
comes in with the same name as the one that started it all
|
|
||||||
at the same level.
|
|
||||||
The tests nest you see.
|
|
||||||
Closing the last test finishes the display.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">void paintMethodStart(string $test_name)</span><br>
|
|
||||||
is called at the start of each test method.
|
|
||||||
The name normally comes from method name.
|
|
||||||
The other test start events behave the same way except
|
|
||||||
that the group test one tells the reporter how large
|
|
||||||
it is in number of held test cases.
|
|
||||||
This is so that the reporter can display a progress bar
|
|
||||||
as the runner churns through the test cases.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">void paintMethodEnd(string $test_name)</span><br>
|
|
||||||
backs out of the test started with the same name.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">void paintFail(string $message)</span><br>
|
|
||||||
paints a failure.
|
|
||||||
By default it just displays the word fail, a breadcrumbs trail
|
|
||||||
showing the current test nesting and the message issued by
|
|
||||||
the assertion.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">void paintPass(string $message)</span><br>
|
|
||||||
by default does nothing.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">string getCss()</span><br>
|
|
||||||
Returns the CSS styles as a string for the page header
|
|
||||||
method.
|
|
||||||
Additional styles have to be appended here if you are
|
|
||||||
not overriding the page header.
|
|
||||||
You will want to use this method in an overriden page header
|
|
||||||
if you want to include the original CSS.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
There are also some accessors to get information on the current
|
|
||||||
state of the test suite.
|
|
||||||
Use these to enrich the display...
|
|
||||||
<ul class="api">
|
|
||||||
<li>
|
|
||||||
<span class="new_code">array getTestList()</span><br>
|
|
||||||
is the first convenience method for subclasses.
|
|
||||||
Lists the current nesting of the tests as a list
|
|
||||||
of test names.
|
|
||||||
The first, top level test case, is first in the
|
|
||||||
list and the current test method will be last.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">integer getPassCount()</span><br>
|
|
||||||
returns the number of passes chalked up so far.
|
|
||||||
Needed for the display at the end.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">integer getFailCount()</span><br>
|
|
||||||
is likewise the number of fails so far.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">integer getExceptionCount()</span><br>
|
|
||||||
is likewise the number of errors so far.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">integer getTestCaseCount()</span><br>
|
|
||||||
is the total number of test cases in the test run.
|
|
||||||
This includes the grouping tests themselves.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="new_code">integer getTestCaseProgress()</span><br>
|
|
||||||
is the number of test cases completed so far.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
One simple modification is to get the HtmlReporter to display
|
|
||||||
the passes as well as the failures and errors...
|
|
||||||
<pre>
|
|
||||||
<strong>class ReporterShowingPasses extends HtmlReporter {
|
|
||||||
|
|
||||||
function paintPass($message) {
|
|
||||||
parent::paintPass($message);
|
|
||||||
print "<span class=\"pass\">Pass</span>: ";
|
|
||||||
$breadcrumb = $this->getTestList();
|
|
||||||
array_shift($breadcrumb);
|
|
||||||
print implode("-&gt;", $breadcrumb);
|
|
||||||
print "-&gt;$message<br />\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getCss() {
|
|
||||||
return parent::getCss() . ' .pass { color: green; }';
|
|
||||||
}
|
|
||||||
}</strong>
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
One method that was glossed over was the <span class="new_code">makeDry()</span>
|
|
||||||
method.
|
|
||||||
If you run this method, with no parameters, on the reporter
|
|
||||||
before the test suite is run no actual test methods
|
|
||||||
will be called.
|
|
||||||
You will still get the events of entering and leaving the
|
|
||||||
test methods and test cases, but no passes or failures etc,
|
|
||||||
because the test code will not actually be executed.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The reason for this is to allow for more sophistcated
|
|
||||||
GUI displays that allow the selection of individual test
|
|
||||||
cases.
|
|
||||||
In order to build a list of possible tests they need a
|
|
||||||
report on the test structure for drawing, say a tree view
|
|
||||||
of the test suite.
|
|
||||||
With a reporter set to dry run that just sends drawing events
|
|
||||||
this is easily accomplished.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="other"></a>Extending the reporter</h2>
|
|
||||||
<p>
|
|
||||||
Rather than simply modifying the existing display, you might want to
|
|
||||||
produce a whole new HTML look, or even generate text or XML.
|
|
||||||
Rather than override every method in
|
|
||||||
<span class="new_code">HtmlReporter</span> we can take one
|
|
||||||
step up the class hiearchy to <span class="new_code">SimpleReporter</span>
|
|
||||||
in the <em>simple_test.php</em> source file.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A do nothing display, a blank canvas for your own creation, would
|
|
||||||
be...
|
|
||||||
<pre>
|
|
||||||
<strong>require_once('simpletest/simpletest.php');</strong>
|
|
||||||
|
|
||||||
class MyDisplay extends SimpleReporter {<strong>
|
|
||||||
</strong>
|
|
||||||
function paintHeader($test_name) { }
|
|
||||||
|
|
||||||
function paintFooter($test_name) { }
|
|
||||||
|
|
||||||
function paintStart($test_name, $size) {<strong>
|
|
||||||
parent::paintStart($test_name, $size);</strong>
|
|
||||||
}
|
|
||||||
|
|
||||||
function paintEnd($test_name, $size) {<strong>
|
|
||||||
parent::paintEnd($test_name, $size);</strong>
|
|
||||||
}
|
|
||||||
|
|
||||||
function paintPass($message) {<strong>
|
|
||||||
parent::paintPass($message);</strong>
|
|
||||||
}
|
|
||||||
|
|
||||||
function paintFail($message) {<strong>
|
|
||||||
parent::paintFail($message);</strong>
|
|
||||||
}
|
|
||||||
|
|
||||||
function paintError($message) {<strong>
|
|
||||||
parent::paintError($message);</strong>
|
|
||||||
}
|
|
||||||
|
|
||||||
function paintException($exception) {<strong>
|
|
||||||
parent::paintException($exception);</strong>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
No output would come from this class until you add it.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The catch with using this low level class is that you must
|
|
||||||
explicitely invoke it in the test script.
|
|
||||||
The "autorun" facility will not be able to use
|
|
||||||
its runtime context (whether it's running in a web browser
|
|
||||||
or the command line) to select the reporter.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You explicitely invoke the test runner like so...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
$test = new TestSuite('File test');
|
|
||||||
$test->addFile('tests/file_test.php');
|
|
||||||
$test->run(<strong>new MyReporter()</strong>);
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
...perhaps like this...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/simpletest.php');
|
|
||||||
require_once('my_reporter.php');
|
|
||||||
|
|
||||||
class MyTest extends TestSuite {
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->addFile('tests/file_test.php');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$test = new MyTest();
|
|
||||||
$test->run(<strong>new MyReporter()</strong>);
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
We'll show how to fit in with "autorun" later.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="cli"></a>The command line reporter</h2>
|
|
||||||
<p>
|
|
||||||
SimpleTest also ships with a minimal command line reporter.
|
|
||||||
The interface mimics JUnit to some extent, but paints the
|
|
||||||
failure messages as they arrive.
|
|
||||||
To use the command line reporter explicitely, substitute it
|
|
||||||
for the HTML version...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
$test = new TestSuite('File test');
|
|
||||||
$test->addFile('tests/file_test.php');
|
|
||||||
$test->run(<strong>new TextReporter()</strong>);
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
Then invoke the test suite from the command line...
|
|
||||||
<pre class="shell">
|
|
||||||
php file_test.php
|
|
||||||
</pre>
|
|
||||||
You will need the command line version of PHP installed
|
|
||||||
of course.
|
|
||||||
A passing test suite looks like this...
|
|
||||||
<pre class="shell">
|
|
||||||
File test
|
|
||||||
OK
|
|
||||||
Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0
|
|
||||||
</pre>
|
|
||||||
A failure triggers a display like this...
|
|
||||||
<pre class="shell">
|
|
||||||
File test
|
|
||||||
1) True assertion failed.
|
|
||||||
in createNewFile
|
|
||||||
FAILURES!!!
|
|
||||||
Test cases run: 1/1, Passes: 0, Failures: 1, Exceptions: 0
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
One of the main reasons for using a command line driven
|
|
||||||
test suite is of using the tester as part of some automated
|
|
||||||
process.
|
|
||||||
To function properly in shell scripts the test script should
|
|
||||||
return a non-zero exit code on failure.
|
|
||||||
If a test suite fails the value <span class="new_code">false</span>
|
|
||||||
is returned from the <span class="new_code">SimpleTest::run()</span>
|
|
||||||
method.
|
|
||||||
We can use that result to exit the script with the desired return
|
|
||||||
code...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
$test = new TestSuite('File test');
|
|
||||||
$test->addFile('tests/file_test.php');
|
|
||||||
<strong>exit ($test->run(new TextReporter()) ? 0 : 1);</strong>
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
Of course we wouldn't really want to create two test scripts,
|
|
||||||
a command line one and a web browser one, for each test suite.
|
|
||||||
The command line reporter includes a method to sniff out the
|
|
||||||
run time environment...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
$test = new TestSuite('File test');
|
|
||||||
$test->addFile('tests/file_test.php');
|
|
||||||
<strong>if (TextReporter::inCli()) {</strong>
|
|
||||||
exit ($test->run(new TextReporter()) ? 0 : 1);
|
|
||||||
<strong>}</strong>
|
|
||||||
$test->run(new HtmlReporter());
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
This is the form used within SimpleTest itself.
|
|
||||||
When you use the "autorun.php", and no
|
|
||||||
test has been run by the end, this is pretty much
|
|
||||||
the code that SimpleTest will run for you implicitely.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In other words, this is gives the same result...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
class MyTest extends TestSuite {
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->addFile('tests/file_test.php');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
<a class="target" name="xml"></a>Remote testing</h2>
|
|
||||||
<p>
|
|
||||||
SimpleTest ships with an <span class="new_code">XmlReporter</span> class
|
|
||||||
used for internal communication.
|
|
||||||
When run the output looks like...
|
|
||||||
<pre class="shell">
|
|
||||||
<?xml version="1.0"?>
|
|
||||||
<run>
|
|
||||||
<group size="4">
|
|
||||||
<name>Remote tests</name>
|
|
||||||
<group size="4">
|
|
||||||
<name>Visual test with 48 passes, 48 fails and 4 exceptions</name>
|
|
||||||
<case>
|
|
||||||
<name>testofunittestcaseoutput</name>
|
|
||||||
<test>
|
|
||||||
<name>testofresults</name>
|
|
||||||
<pass>This assertion passed</pass>
|
|
||||||
<fail>This assertion failed</fail>
|
|
||||||
</test>
|
|
||||||
<test>
|
|
||||||
...
|
|
||||||
</test>
|
|
||||||
</case>
|
|
||||||
</group>
|
|
||||||
</group>
|
|
||||||
</run>
|
|
||||||
</pre>
|
|
||||||
To get your normal test cases to produce this format, on the
|
|
||||||
command line add the <span class="new_code">--xml</span> flag.
|
|
||||||
<pre class="shell">
|
|
||||||
php my_test.php --xml
|
|
||||||
</pre>
|
|
||||||
You can do teh same thing in the web browser by adding the
|
|
||||||
URL parameter <span class="new_code">xml=1</span>.
|
|
||||||
Any true value will do.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You can consume this format with the parser
|
|
||||||
supplied as part of SimpleTest itself.
|
|
||||||
This is called <span class="new_code">SimpleTestXmlParser</span> and
|
|
||||||
resides in <em>xml.php</em> within the SimpleTest package...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/xml.php');
|
|
||||||
|
|
||||||
...
|
|
||||||
$parser = new SimpleTestXmlParser(new HtmlReporter());
|
|
||||||
$parser->parse($test_output);
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
The <span class="new_code">$test_output</span> should be the XML format
|
|
||||||
from the XML reporter, and could come from say a command
|
|
||||||
line run of a test case.
|
|
||||||
The parser sends events to the reporter just like any
|
|
||||||
other test run.
|
|
||||||
There are some odd occasions where this is actually useful.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Most likely it's when you want to isolate a problematic crash
|
|
||||||
prone test.
|
|
||||||
You can collect the XML output using the backtick operator
|
|
||||||
from another test.
|
|
||||||
In that way it runs in its own process...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
require_once('simpletest/xml.php');
|
|
||||||
|
|
||||||
if (TextReporter::inCli()) {
|
|
||||||
$parser = new SimpleTestXmlParser(new TextReporter());
|
|
||||||
} else {
|
|
||||||
$parser = new SimpleTestXmlParser(new HtmlReporter());
|
|
||||||
}
|
|
||||||
$parser->parse(`php flakey_test.php --xml`);
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Another use is breaking up large test suites.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A problem with large test suites is thet they can exhaust
|
|
||||||
the default 16Mb memory limit on a PHP process.
|
|
||||||
By having the test groups output in XML and run in
|
|
||||||
separate processes, the output can be reparsed to
|
|
||||||
aggregate the results into a much smaller footprint top level
|
|
||||||
test.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Because the XML output can come from anywhere, this opens
|
|
||||||
up the possibility of aggregating test runs from remote
|
|
||||||
servers.
|
|
||||||
A test case already exists to do this within the SimpleTest
|
|
||||||
framework, but it is currently experimental...
|
|
||||||
<pre>
|
|
||||||
<?php
|
|
||||||
<strong>require_once('../remote.php');</strong>
|
|
||||||
require_once('simpletest/autorun.php');
|
|
||||||
|
|
||||||
$test_url = ...;
|
|
||||||
$dry_url = ...;
|
|
||||||
|
|
||||||
class MyTestOnAnotherServer extends RemoteTestCase {
|
|
||||||
function __construct() {
|
|
||||||
$test_url = ...
|
|
||||||
parent::__construct($test_url, $test_url . ' --dry');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</pre>
|
|
||||||
The <span class="new_code">RemoteTestCase</span> takes the actual location
|
|
||||||
of the test runner, basically a web page in XML format.
|
|
||||||
It also takes the URL of a reporter set to do a dry run.
|
|
||||||
This is so that progress can be reported upward correctly.
|
|
||||||
The <span class="new_code">RemoteTestCase</span> can be added to test suites
|
|
||||||
just like any other test suite.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
References and related information...
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
|
|
||||||
gives full detail on the classes and assertions available.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="menu_back"><div class="menu">
|
|
||||||
<a href="index.html">SimpleTest</a>
|
|
||||||
|
|
|
||||||
<a href="overview.html">Overview</a>
|
|
||||||
|
|
|
||||||
<a href="unit_test_documentation.html">Unit tester</a>
|
|
||||||
|
|
|
||||||
<a href="group_test_documentation.html">Group tests</a>
|
|
||||||
|
|
|
||||||
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
||||||
|
|
|
||||||
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
||||||
|
|
|
||||||
<span class="chosen">Reporting</span>
|
|
||||||
|
|
|
||||||
<a href="expectation_documentation.html">Expectations</a>
|
|
||||||
|
|
|
||||||
<a href="web_tester_documentation.html">Web tester</a>
|
|
||||||
|
|
|
||||||
<a href="form_testing_documentation.html">Testing forms</a>
|
|
||||||
|
|
|
||||||
<a href="authentication_documentation.html">Authentication</a>
|
|
||||||
|
|
|
||||||
<a href="browser_documentation.html">Scriptable browser</a>
|
|
||||||
</div></div>
|
|
||||||
<div class="copyright">
|
|
||||||
Copyright<br>Marcus Baker 2006
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user