diff --git a/test/model/product/.create.php.swp b/test/model/product/.create.php.swp
new file mode 100644
index 0000000000..611e41bf9f
Binary files /dev/null and b/test/model/product/.create.php.swp differ
diff --git a/test/model/product/getlatestproject.php b/test/model/product/getlatestproject.php
new file mode 100755
index 0000000000..e136a077e5
--- /dev/null
+++ b/test/model/product/getlatestproject.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getLatestProject();
+cid=1
+pid=1
+
+测试产品25关联的最后一个未关闭的项目,按begin字段排序 >> 395
+测试产品38关联的最后一个未关闭的项目,按begin字段排序 >> 688
+传入不存在的产品 >> 没有数据
+
+*/
+
+$product = new Product('admin');
+
+$t_project25 = array('id'=>'25');
+$t_project38 = array('id'=>'38');
+$t_project101 = array('id'=>'101');
+
+r($product->testGetLatestProject($t_project25['id'])) && p('id') && e('395'); // 测试产品25关联的最后一个未关闭的项目,按begin字段排序
+r($product->testGetLatestProject($t_project38['id'])) && p('id') && e('688'); // 测试产品38关联的最后一个未关闭的项目,按begin字段排序
+r($product->testGetLatestProject($t_project101['id'])) && p() && e('没有数据'); // 传入不存在的产品
\ No newline at end of file
diff --git a/test/model/product/getlist.php b/test/model/product/getlist.php
new file mode 100755
index 0000000000..749896f32c
--- /dev/null
+++ b/test/model/product/getlist.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+返回项目集1下的产品数量 >> 9
+测试传入programID=0的情况 >> 100
+传入不存在的项目集 >> 0
+返回项目集1下的未关闭的产品数量 >> 5
+获取所有的未关闭的产品数量 >> 60
+返回项目集1下的关闭了的产品数量 >> 4
+返回所有的未关闭的产品数量 >> 40
+返回项目集1下的与当前用户有关系的产品数量 >> 0
+返回项目集1下产品线1的产品数量 >> 9
+返回项目集1下产品线2的产品数量 >> 0
+
+*/
+
+$adminTester = new Product('admin');
+
+$t_numproject = array('0','1', '2', '11');
+
+r($adminTester->getAllProductsCount($t_numproject[1])) && p() && e('9'); // 返回项目集1下的产品数量
+r($adminTester->getAllProductsCount($t_numproject[0])) && p() && e('100'); // 测试传入programID=0的情况
+r($adminTester->getAllProductsCount($t_numproject[3])) && p() && e('0'); // 传入不存在的项目集
+r($adminTester->getNoclosedProductsCount($t_numproject[1])) && p() && e('5'); // 返回项目集1下的未关闭的产品数量
+r($adminTester->getNoclosedProductsCount($t_numproject[0])) && p() && e('60'); // 获取所有的未关闭的产品数量
+r($adminTester->getClosedProductsCount($t_numproject[1])) && p() && e('4'); // 返回项目集1下的关闭了的产品数量
+r($adminTester->getClosedProductsCount($t_numproject[0])) && p() && e('40'); // 返回所有的未关闭的产品数量
+r($adminTester->getInvolvedProductsCount($t_numproject[1])) && p() && e('0'); // 返回项目集1下的与当前用户有关系的产品数量
+r($adminTester->countProductsByLine($t_numproject[1], $t_numproject[1])) && p() && e('9'); // 返回项目集1下产品线1的产品数量
+r($adminTester->countProductsByLine($t_numproject[1], $t_numproject[2])) && p() && e('0'); // 返回项目集1下产品线2的产品数量
\ No newline at end of file
diff --git a/test/model/product/getpairs.php b/test/model/product/getpairs.php
new file mode 100755
index 0000000000..f67fcefbba
--- /dev/null
+++ b/test/model/product/getpairs.php
@@ -0,0 +1,95 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试项目集10下的11号产品 >> 正常产品11
+测试项目集10下的55号产品 >> 多分支产品55
+测试项目集10下的99号产品 >> 多平台产品99
+测试不存在的项目集 >> 没有数据
+返回所有产品的数量 >> 100
+返回项目集10下的所有产品 >> 9
+测试项目集10下的未关闭产品5 >> 正常产品6
+返回项目集10下的未关闭产品的数量 >> 5
+
+*/
+
+/*class Tester
+{
+ public function __construct($user, $orderBy = 'id_desc')
+ {
+ global $tester;
+ su($user);
+ $this->product = $tester->loadModel('product');
+ $this->config = new stdclass();
+ $this->config->product->orderBy = $orderBy;
+ }
+
+ public function getProductPairs($programID)
+ {
+ $pairs = $this->product->getPairs('', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ public function getProductPairsCount($programID)
+ {
+ $pairsCount = count($this->getProductPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ public function getAllPairs($programID)
+ {
+ $pairs = $this->product->getPairs('all', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ public function getAllPairsCount($programID)
+ {
+ $pairsCount = count($this->getAllPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ public function getNoclosedPairs($programID)
+ {
+ $pairs = $this->product->getPairs('noclosed', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ public function getNoclosedPairsCount($programID)
+ {
+ $pairsCount = count($this->getNoclosedPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ public function getProductPairsByOrder($programID, $mode = '', $orderBy = 'id_desc')
+ {
+ $this->config->product->orderBy = $orderBy;
+ $pairs = $this->product->getPairs($mode, $programID);
+ return checkOrder($pairs, $orderBy);
+ }
+}*/
+
+$tester = new Product('admin');
+
+$t_peoduct10 = array('programID'=>'10');
+$t_noproduct = array('programID'=>'11');
+$t_alproduct = array('programID'=>'0');
+$t_notclose5 = array('programID'=>'5');
+
+r($tester->getProductPairs($t_peoduct10['programID'])) && p('11') && e('正常产品11'); // 测试项目集10下的11号产品
+r($tester->getProductPairs($t_peoduct10['programID'])) && p('55') && e('多分支产品55'); // 测试项目集10下的55号产品
+r($tester->getProductPairs($t_peoduct10['programID'])) && p('99') && e('多平台产品99'); // 测试项目集10下的99号产品
+r($tester->getProductPairs($t_noproduct['programID'])) && p() && e('没有数据'); // 测试不存在的项目集
+r($tester->getProductPairsCount($t_alproduct['programID'])) && p() && e('100'); // 返回所有产品的数量
+r($tester->getProductPairsCount($t_peoduct10['programID'])) && p() && e('9'); // 返回项目集10下的所有产品
+r($tester->getNoclosedPairs($t_notclose5['programID'])) && p('6') && e('正常产品6'); // 测试项目集10下的未关闭产品5
+r($tester->getNoclosedPairsCount($t_peoduct10['programID'])) && p() && e('5'); // 返回项目集10下的未关闭产品的数量
\ No newline at end of file
diff --git a/test/model/product/getprojectlistbyproduct.php b/test/model/product/getprojectlistbyproduct.php
new file mode 100755
index 0000000000..f6bef8ec15
--- /dev/null
+++ b/test/model/product/getprojectlistbyproduct.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getProjectListByProduct();
+cid=1
+pid=1
+
+返回产品1关联的项目11名字 >> 项目1
+返回产品1关联的项目21名字 >> 项目11
+传入不存在的产品 >> 没有数据
+
+*/
+
+$tester = new Product('admin');
+
+$t_retion = array('1', '1', '101');
+
+//var_dump($tester->getAllProjectsByProduct($t_retion[0]));die;
+r($tester->getAllProjectsByProduct($t_retion[0])) && p('11:name') && e('项目1'); // 返回产品1关联的项目11名字
+r($tester->getAllProjectsByProduct($t_retion[1])) && p('21:name') && e('项目11'); // 返回产品1关联的项目21名字
+r($tester->getAllProjectsByProduct($t_retion[2])) && p() && e('没有数据'); // 传入不存在的产品
\ No newline at end of file
diff --git a/test/model/product/getprojectpairsbyproduct.php b/test/model/product/getprojectpairsbyproduct.php
new file mode 100755
index 0000000000..94ce620b08
--- /dev/null
+++ b/test/model/product/getprojectpairsbyproduct.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getProjectPairsByProduct();
+cid=1
+pid=1
+
+返回产品1关联的项目11名字 >> 项目1
+返回产品1关联的项目21名字 >> 项目11
+传入不存在的产品 >> 没有数据
+返回id为15的项目名 >> 项目5
+传入不存在的项目id >> 没有数据
+
+*/
+
+$tester = new Product('admin');
+
+$t_return = array('1', '101', '15', '7010');
+
+r($tester->getProjectPairsByProductID($t_return[0])) && p('11') && e('项目1'); // 返回产品1关联的项目11名字
+r($tester->getProjectPairsByProductID($t_return[0])) && p('21') && e('项目11'); // 返回产品1关联的项目21名字
+r($tester->getProjectPairsByProductID($t_return[1])) && p() && e('没有数据'); // 传入不存在的产品
+r($tester->getAppendProject($t_return[2])) && p('15') && e('项目5'); // 返回id为15的项目名
+r($tester->getAppendProject($t_return[3])) && p() && e('没有数据'); // 传入不存在的项目id
\ No newline at end of file
diff --git a/test/model/product/isclickable.php b/test/model/product/isclickable.php
new file mode 100755
index 0000000000..fc046148e0
--- /dev/null
+++ b/test/model/product/isclickable.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+isClickable();
+cid=1
+pid=1
+
+status为normal,action为close >> true
+status为close,action为close >> false
+status为normal,action为start >> true
+status为close,action为start >> true
+
+*/
+
+$adminTester = new Product('admin');
+
+$t_status = array('2', '75', 'close', 'start');
+
+r($adminTester->testIsClickable($t_status[0], $t_status[2])) && p() && e('true'); // status为normal,action为close
+r($adminTester->testIsClickable($t_status[1], $t_status[2])) && p() && e('false'); // status为close,action为close
+r($adminTester->testIsClickable($t_status[0], $t_status[3])) && p() && e('true'); // status为normal,action为start
+r($adminTester->testIsClickable($t_status[1], $t_status[3])) && p() && e('true'); // status为close,action为start
\ No newline at end of file
diff --git a/test/model/product/move.sh b/test/model/product/move.sh
new file mode 100644
index 0000000000..83d843101e
--- /dev/null
+++ b/test/model/product/move.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+#This script is use to rename files
+for file in * ;
+do mv $file `echo $file | tr 'A-Z' 'a-z'`;
+done
diff --git a/test/model/product_bak/create.php b/test/model/product_bak/create.php
new file mode 100755
index 0000000000..87abb462a7
--- /dev/null
+++ b/test/model/product_bak/create.php
@@ -0,0 +1,66 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试正常的创建 >> case1
+测试不填产品代号的情况 >> 『code』不能为空。
+测试创建重复的产品 >> 『code』已经有『testcase1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+测试不填产品名称的情况 >> 『name』不能为空。
+测试传入name和code >> case3,testcase3
+测试传入program、name、code >> 3,case4,testcase4
+测试传入program、name、code、type、status >> 4,branch,closed
+
+*/
+
+$config = new stdClass();
+$config->createFields->product = array('program' => '', 'name' => '', 'code' => '', 'PO' => '', 'QD' => '', 'RD' => '', 'type' => 'normal', 'status' => 'normal', 'desc' => '', 'acl' => 'private');
+/*
+function createObject($module = '', $param = array())
+{
+ global $config;
+ foreach($config->createFields->$module as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ global $tester;
+ $objectModel = $tester->loadModel($module);
+ $objectID = $objectModel->create();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $objectModel->getByID($objectID);
+ return $object;
+ }
+}*/
+$createObject = new Product('admin');
+
+$create1 = array('name' => 'case1', 'code' => 'testcase1');
+$create2 = array('name' => 'case2');
+$create3 = array('name' => 'case1', 'code' => 'testcase1');
+$create4 = array('code' => 'testcase1');
+$create5 = array('name' => 'case3', 'code' => 'testcase3');
+$create6 = array('program' => '3', 'name' => 'case4', 'code' => 'testcase4');
+$create7 = array('program' => '4', 'name' => 'case5', 'code' => 'testcase5', 'type' => 'branch', 'status' => 'closed');
+
+r($createObject->createObject('product', $create1)) && p('name') && e('case1'); // 测试正常的创建
+r($createObject->createObject('product', $create2)) && p('code:0') && e('『code』不能为空。'); // 测试不填产品代号的情况
+r($createObject->createObject('product', $create3)) && p('code:0') && e('『code』已经有『testcase1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 测试创建重复的产品
+r($createObject->createObject('product', $create4)) && p('name:0') && e('『name』不能为空。'); // 测试不填产品名称的情况
+r($createObject->createObject('product', $create5)) && p('name,code') && e('case3,testcase3'); // 测试传入name和code
+r($createObject->createObject('product', $create6)) && p('program,name,code') && e('3,case4,testcase4'); // 测试传入program、name、code
+r($createObject->createObject('product', $create7)) && p('program,type,status') && e('4,branch,closed'); // 测试传入program、name、code、type、status
+system("./ztest init");
\ No newline at end of file
diff --git a/test/model/product_bak/getLatestProject.php b/test/model/product_bak/getLatestProject.php
new file mode 100755
index 0000000000..3b6f42f1dc
--- /dev/null
+++ b/test/model/product_bak/getLatestProject.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getLatestProject();
+cid=1
+pid=1
+
+测试产品25关联的最后一个未关闭的项目,按begin字段排序 >> 315
+测试产品38关联的最后一个未关闭的项目,按begin字段排序 >> 阶段588
+传入不存在的产品 >> 没有数据
+
+*/
+
+$project = new Product('admin');
+
+#var_dump($z->testGetLatestProject(38));die;
+r($project->testGetLatestProject(25)) && p('id') && e('315'); // 测试产品25关联的最后一个未关闭的项目,按begin字段排序
+r($project->testGetLatestProject(38)) && p('name') && e('阶段588'); // 测试产品38关联的最后一个未关闭的项目,按begin字段排序
+r($project->testGetLatestProject(101)) && p() && e('没有数据'); // 传入不存在的产品
\ No newline at end of file
diff --git a/test/model/product_bak/getList.php b/test/model/product_bak/getList.php
new file mode 100755
index 0000000000..9843c25e3a
--- /dev/null
+++ b/test/model/product_bak/getList.php
@@ -0,0 +1,102 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+返回项目集1下的产品数量 >> 9
+测试传入programID=0的情况 >> 100
+传入不存在的项目集 >> 0
+返回项目集1下的未关闭的产品数量 >> 5
+获取所有的未关闭的产品数量 >> 60
+返回项目集1下的关闭了的产品数量 >> 4
+返回所有的未关闭的产品数量 >> 40
+返回项目集1下的与当前用户有关系的产品数量 >> 0
+返回项目集1下产品线1的产品数量 >> 9
+返回项目集1下产品线2的产品数量 >> 0
+
+*/
+
+class Tester
+{
+ public function __construct($user)
+ {
+ global $tester;
+ su($user);
+ $this->product = $tester->loadModel('product');
+ }
+ public function getAllProducts($programID)
+ {
+ return $this->product->getList($programID);
+ }
+ public function getAllProductsCount($programID)
+ {
+ return count($this->getAllProducts($programID));
+ }
+
+ public function getNoclosedProducts($programID)
+ {
+ return $this->product->getList($programID, 'noclosed');
+ }
+ public function getNoclosedProductsCount($programID)
+ {
+ return count($this->getNoclosedProducts($programID));
+ }
+
+ public function getClosedProducts($programID)
+ {
+ return $this->product->getList($programID, 'closed');
+ }
+ public function getClosedProductsCount($programID)
+ {
+ return count($this->getClosedProducts($programID));
+ }
+
+ public function getInvolvedProducts($programID)
+ {
+ return $this->product->getList($programID, 'involved');
+ }
+ public function getInvolvedProductsCount($programID)
+ {
+ return count($this->getInvolvedProducts($programID));
+ }
+
+ public function getProductsByLine($programID, $line = 0)
+ {
+ return $this->product->getList($programID, 'all', 0, $line);
+ }
+ public function countProductsByLine($programID, $line = 0)
+ {
+ return count($this->getProductsByLine($programID, $line));
+ }
+
+ public function getProductList($programID, $status = 'all', $line = 0)
+ {
+ return $this->product->getList($programID, $status, 0, $line);
+ }
+ public function getProductCount($programID, $status = 'all', $line = 0)
+ {
+ return count($this->getProductList($programID, $status, $line));
+ }
+}
+
+$adminTester = new Tester('admin');
+
+r($adminTester->getAllProductsCount(1)) && p() && e('9'); // 返回项目集1下的产品数量
+r($adminTester->getAllProductsCount(0)) && p() && e('100'); // 测试传入programID=0的情况
+r($adminTester->getAllProductsCount(11)) && p() && e('0'); // 传入不存在的项目集
+
+r($adminTester->getNoclosedProductsCount(1)) && p() && e('5'); // 返回项目集1下的未关闭的产品数量
+r($adminTester->getNoclosedProductsCount(0)) && p() && e('60'); // 获取所有的未关闭的产品数量
+
+r($adminTester->getClosedProductsCount(1)) && p() && e('4'); // 返回项目集1下的关闭了的产品数量
+r($adminTester->getClosedProductsCount(0)) && p() && e('40'); // 返回所有的未关闭的产品数量
+
+r($adminTester->getInvolvedProductsCount(1)) && p() && e('0'); // 返回项目集1下的与当前用户有关系的产品数量
+
+r($adminTester->countProductsByLine(1, 1)) && p() && e('9'); // 返回项目集1下产品线1的产品数量
+r($adminTester->countProductsByLine(1, 2)) && p() && e('0'); // 返回项目集1下产品线2的产品数量
\ No newline at end of file
diff --git a/test/model/product_bak/getPairs.php b/test/model/product_bak/getPairs.php
new file mode 100755
index 0000000000..88967403cf
--- /dev/null
+++ b/test/model/product_bak/getPairs.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试项目集10下的11号产品 >> 正常产品11
+测试项目集10下的55号产品 >> 多分支产品55
+测试项目集10下的99号产品 >> 多平台产品99
+测试不存在的项目集 >> 没有数据
+返回所有产品的数量 >> 100
+返回项目集10下的所有产品 >> 9
+测试项目集10下的未关闭产品5 >> 正常产品6
+返回项目集10下的未关闭产品的数量 >> 5
+测试顺序program_desc >> 1
+测试顺序program_asc >> 1
+测试顺序type_desc >> 1
+
+*/
+
+$tester = new productBox('admin');
+var_dump($tester->getProductPairsByOrder(10, '', 'program_desc'));die;
+r($tester->getProductPairs(10)) && p('11') && e('正常产品11'); // 测试项目集10下的11号产品
+r($tester->getProductPairs(10)) && p('55') && e('多分支产品55'); // 测试项目集10下的55号产品
+r($tester->getProductPairs(10)) && p('99') && e('多平台产品99'); // 测试项目集10下的99号产品
+r($tester->getProductPairs(11)) && p() && e('没有数据'); // 测试不存在的项目集
+
+r($tester->getProductPairsCount(0)) && p() && e('100'); // 返回所有产品的数量
+r($tester->getProductPairsCount(10)) && p() && e('9'); // 返回项目集10下的所有产品
+r($tester->getNoclosedPairs(5)) && p('6') && e('正常产品6'); // 测试项目集10下的未关闭产品5
+r($tester->getNoclosedPairsCount(10)) && p() && e('5'); // 返回项目集10下的未关闭产品的数量
+
+r($tester->getProductPairsByOrder(10, '', 'program_desc')) && p() && e('1'); // 测试顺序program_desc
+r($tester->getProductPairsByOrder(11, '', 'program_asc')) && p() && e('1'); // 测试顺序program_asc
+r($tester->getProductPairsByOrder(11, '', 'type_desc')) && p() && e('1'); // 测试顺序type_desc
\ No newline at end of file
diff --git a/test/model/product_bak/getPairscopy.php b/test/model/product_bak/getPairscopy.php
new file mode 100755
index 0000000000..a0bbf5f244
--- /dev/null
+++ b/test/model/product_bak/getPairscopy.php
@@ -0,0 +1,95 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试项目集10下的11号产品 >> 正常产品11
+测试项目集10下的55号产品 >> 多分支产品55
+测试项目集10下的99号产品 >> 多平台产品99
+测试不存在的项目集 >> 没有数据
+返回所有产品的数量 >> 100
+返回项目集10下的所有产品 >> 9
+测试项目集10下的未关闭产品5 >> 正常产品6
+返回项目集10下的未关闭产品的数量 >> 5
+测试顺序program_desc >> 1
+测试顺序program_asc >> 1
+测试顺序type_desc >> 1
+
+*/
+
+class Tester
+{
+ public function __construct($user, $orderBy = 'id_desc')
+ {
+ global $tester;
+ su($user);
+ $this->product = $tester->loadModel('product');
+ $this->config = new stdclass();
+ $this->config->product->orderBy = $orderBy;
+ }
+
+ public function getProductPairs($programID)
+ {
+ $pairs = $this->product->getPairs('', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ public function getProductPairsCount($programID)
+ {
+ $pairsCount = count($this->getProductPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ public function getAllPairs($programID)
+ {
+ $pairs = $this->product->getPairs('all', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ public function getAllPairsCount($programID)
+ {
+ $pairsCount = count($this->getAllPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ public function getNoclosedPairs($programID)
+ {
+ $pairs = $this->product->getPairs('noclosed', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ public function getNoclosedPairsCount($programID)
+ {
+ $pairsCount = count($this->getNoclosedPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ public function getProductPairsByOrder($programID, $mode = '', $orderBy = 'id_desc')
+ {
+ $this->config->product->orderBy = $orderBy;
+ $pairs = $this->product->getPairs($mode, $programID);
+ return checkOrder($pairs, $orderBy);
+ }
+}
+
+$tester = new Tester('admin');
+
+r($tester->getProductPairs(10)) && p('11' && e('正常产品11'); // 测试项目集10下的11号产品
+r($tester->getProductPairs(10)) && p('55') && e('多分支产品55'); // 测试项目集10下的55号产品
+r($tester->getProductPairs(10)) && p('99') && e('多平台产品99'); // 测试项目集10下的99号产品
+r($tester->getProductPairs(11)) && p() && e('没有数据'); // 测试不存在的项目集
+r($tester->getProductPairsCount(0)) && p() && e('100'); // 返回所有产品的数量
+r($tester->getProductPairsCount(10)) && p() && e('9'); // 返回项目集10下的所有产品
+r($tester->getNoclosedPairs(5)) && p('6') && e('正常产品6'); // 测试项目集10下的未关闭产品5
+r($tester->getNoclosedPairsCount(10)) && p() && e('5'); // 返回项目集10下的未关闭产品的数量
+r($tester->getProductPairsByOrder(10, '', 'program_desc')) && p() && e('1'); // 测试顺序program_desc
+r($tester->getProductPairsByOrder(11, '', 'program_asc')) && p() && e('1'); // 测试顺序program_asc
+r($tester->getProductPairsByOrder(11, '', 'type_desc')) && p() && e('1'); // 测试顺序type_desc
\ No newline at end of file
diff --git a/test/model/product_bak/getProjectListByProduct.php b/test/model/product_bak/getProjectListByProduct.php
new file mode 100755
index 0000000000..70d7480131
--- /dev/null
+++ b/test/model/product_bak/getProjectListByProduct.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getProjectListByProduct();
+cid=1
+pid=1
+
+返回产品1关联的项目11名字 >> 项目11
+返回产品1关联的项目21名字 >> 项目1
+传入不存在的产品 >> 没有数据
+
+*/
+
+class Tester
+{
+ public function __construct($user)
+ {
+ global $tester;
+ su($user);
+ $this->product = $tester->loadModel('product');
+ }
+
+ public function getAllProjectsByProduct($productID)
+ {
+ $projects = $this->product->getProjectListByProduct($productID, 'all');
+ if($projects == array()) return '没有数据';
+ return $projects;
+ }
+
+ public function getProjectsByStatus($productID, $status)
+ {
+ $projects = $this->product->getProjectListByProduct($productID, $browseType);
+ if($projects == array()) return '没有数据';
+ return $projects;
+ }
+}
+
+$tester = new Tester('admin');
+r($tester->getAllProjectsByProduct(1)) && p('21:name') && e('项目11'); // 返回产品1关联的项目11名字
+r($tester->getAllProjectsByProduct(1)) && p('11:name') && e('项目1'); // 返回产品1关联的项目21名字
+r($tester->getAllProjectsByProduct(101)) && p() && e('没有数据'); // 传入不存在的产品
\ No newline at end of file
diff --git a/test/model/product_bak/getProjectPairsByProduct.php b/test/model/product_bak/getProjectPairsByProduct.php
new file mode 100755
index 0000000000..db4b5a7565
--- /dev/null
+++ b/test/model/product_bak/getProjectPairsByProduct.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getProjectPairsByProduct();
+cid=1
+pid=1
+
+返回产品1关联的项目11名字 >> 项目1
+返回产品1关联的项目21名字 >> 项目11
+传入不存在的产品 >> 没有数据
+返回id为15的项目名 >> 项目5
+传入不存在的项目id >> 没有数据
+
+*/
+
+$tester = new productBox('admin');
+
+r($tester->getProjectPairsByProductID(1)) && p('11') && e('项目1'); // 返回产品1关联的项目11名字
+r($tester->getProjectPairsByProductID(1)) && p('21') && e('项目11'); // 返回产品1关联的项目21名字
+r($tester->getProjectPairsByProductID(101)) && p() && e('没有数据'); // 传入不存在的产品
+
+r($tester->getAppendProject(15)) && p('15') && e('项目5'); // 返回id为15的项目名
+r($tester->getAppendProject(701)) && p() && e('没有数据'); // 传入不存在的项目id
\ No newline at end of file
diff --git a/test/model/product_bak/isClickable.php b/test/model/product_bak/isClickable.php
new file mode 100755
index 0000000000..2555e3b077
--- /dev/null
+++ b/test/model/product_bak/isClickable.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+isClickable();
+cid=1
+pid=1
+
+status为normal,action为close >> true
+status为close,action为close >> false
+status为normal,action为start >> true
+status为close,action为start >> true
+
+*/
+
+$adminTester = new productBox('admin');
+
+r($adminTester->testIsClickable(2, 'close')) && p() && e('true'); // status为normal,action为close
+r($adminTester->testIsClickable(75, 'close')) && p() && e('false'); // status为close,action为close
+r($adminTester->testIsClickable(2, 'start')) && p() && e('true'); // status为normal,action为start
+r($adminTester->testIsClickable(75, 'start')) && p() && e('true'); // status为close,action为start
\ No newline at end of file
diff --git a/test/model/product_bak/update.php b/test/model/product_bak/update.php
new file mode 100755
index 0000000000..5dc937d9fc
--- /dev/null
+++ b/test/model/product_bak/update.php
@@ -0,0 +1,69 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试更新产品名称 >> name,正常产品2,john
+测试更新产品代号 >> code,code2,newcode1
+测试更新产品名称和代号 >> name,john,jack;code,newcode1,newcode2
+测试不更改产品名称 >> 没有数据更新
+测试不更改产品代号 >> 没有数据更新
+测试同一项目集下产品名称不能重复 >> 『产品名称』已经有『jack』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+测试同一项目集下产品代号不能重复 >> 『产品代号』已经有『newcode2』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+
+function updateObject($module, $objectID, $param = array())
+{
+ global $tester;
+ $objectModel = $tester->loadModel($module);
+
+ $object = $objectModel->getById($objectID);
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $objectModel->update($objectID);
+ if($change == array()) $change = '没有数据更新';
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $change;
+ }
+}
+
+$case1 = array('name' => 'john');
+$case2 = array('code' => 'newcode1');
+$case3 = array('name' => 'jack', 'code' => 'newcode2');
+$case4 = array('name' => 'jack');
+$case5 = array('code' => 'newcode2');
+$case6 = array('name' => 'jack');
+$case7 = array('code' => 'newcode2');
+
+r(updateObject('product', 2, $case1)) && p('0:field,old,new') && e('name,正常产品2,john'); // 测试更新产品名称
+r(updateObject('product', 2, $case2)) && p('0:field,old,new') && e('code,code2,newcode1'); // 测试更新产品代号
+r(updateObject('product', 2, $case3)) && p('0:field,old,new;1:field,old,new') && e('name,john,jack;code,newcode1,newcode2'); // 测试更新产品名称和代号
+r(updateObject('product', 2, $case4)) && p() && e('没有数据更新'); // 测试不更改产品名称
+r(updateObject('product', 2, $case5)) && p() && e('没有数据更新'); // 测试不更改产品代号
+r(updateObject('product', 13, $case6)) && p('name:0') && e('『产品名称』已经有『jack』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 测试同一项目集下产品名称不能重复
+r(updateObject('product', 13, $case7)) && p('code:0') && e('『产品代号』已经有『newcode2』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 测试同一项目集下产品代号不能重复
+
+system("./ztest init");
\ No newline at end of file
diff --git a/test/model/program/a.txt b/test/model/program/a.txt
new file mode 100644
index 0000000000..4b762b4d81
--- /dev/null
+++ b/test/model/program/a.txt
@@ -0,0 +1,2441 @@
+
123Array
+(
+ [my] => Array
+ (
+ [0] => stdClass Object
+ (
+ [name] => 项目集3
+ [products] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 4
+ [program] => 3
+ [name] => 正常产品4
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 4
+ [id] => 14
+ [name] => 项目4
+ [status] => doing
+ [end] => 2022-04-04
+ [execution] => stdClass Object
+ (
+ [id] => 644
+ [project] => 14
+ [name] => 迭代544
+ [end] => 2022-04-04
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 6
+ [totalEstimate] => 4
+ [totalLeft] => 4
+ [totalReal] => 10
+ [progress] => 60
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 58
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 4
+ [id] => 24
+ [name] => 项目14
+ [status] => doing
+ [end] => 2020-02-14
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 654
+ [project] => 24
+ [name] => 迭代554
+ [end] => 2020-02-14
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 6
+ [totalEstimate] => 3
+ [totalLeft] => 3
+ [totalReal] => 9
+ [progress] => 67
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 55
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 15
+ [program] => 3
+ [name] => 正常产品15
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 43
+ [product] => 15
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 44
+ [product] => 15
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 45
+ [product] => 15
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 15
+ [id] => 35
+ [name] => 项目25
+ [status] => wait
+ [end] => 2019-01-25
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 59
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 48
+ [program] => 3
+ [name] => 多分支产品48
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 142
+ [product] => 48
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 143
+ [product] => 48
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 144
+ [product] => 48
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 48
+ [id] => 68
+ [name] => 项目58
+ [status] => wait
+ [end] => 2020-10-04
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 698
+ [project] => 68
+ [name] => 阶段598
+ [end] => 2020-10-04
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 10
+ [totalEstimate] => 3
+ [totalLeft] => 3
+ [totalReal] => 13
+ [progress] => 77
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 67
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [id] => 59
+ [program] => 3
+ [name] => 多分支产品59
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 59
+ [id] => 69
+ [name] => 项目59
+ [status] => doing
+ [end] => 2021-11-05
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 59
+ [id] => 79
+ [name] => 项目69
+ [status] => doing
+ [end] => 2019-09-15
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 68
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [4] => stdClass Object
+ (
+ [id] => 81
+ [program] => 3
+ [name] => 多平台产品81
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 241
+ [product] => 81
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 242
+ [product] => 81
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 243
+ [product] => 81
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 81
+ [id] => 11
+ [name] => 项目1
+ [status] => wait
+ [end] => 2019-01-01
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 40
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 81
+ [id] => 91
+ [name] => 项目81
+ [status] => wait
+ [end] => 2019-09-27
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 41
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [5] => stdClass Object
+ (
+ [id] => 92
+ [program] => 3
+ [name] => 多平台产品92
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 92
+ [id] => 12
+ [name] => 项目2
+ [status] => wait
+ [end] => 2020-02-02
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 642
+ [project] => 12
+ [name] => 迭代542
+ [end] => 2020-02-02
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 4
+ [totalEstimate] => 2
+ [totalLeft] => 2
+ [totalReal] => 6
+ [progress] => 67
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 51
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 92
+ [id] => 22
+ [name] => 项目12
+ [status] => doing
+ [end] => 2022-12-12
+ [execution] => stdClass Object
+ (
+ [id] => 652
+ [project] => 22
+ [name] => 迭代552
+ [end] => 2022-12-12
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 4
+ [totalEstimate] => 1
+ [totalLeft] => 0
+ [totalReal] => 4
+ [progress] => 100
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [6] => stdClass Object
+ (
+ [id] => 103
+ [program] => 3
+ [name] => case4
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 307
+ [product] => 103
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 308
+ [product] => 103
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 309
+ [product] => 103
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [name] => 项目集4
+ [products] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 5
+ [program] => 4
+ [name] => 正常产品5
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 5
+ [id] => 15
+ [name] => 项目5
+ [status] => doing
+ [end] => 2019-05-05
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 16
+ [program] => 4
+ [name] => 正常产品16
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 46
+ [product] => 16
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 47
+ [product] => 16
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 48
+ [product] => 16
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 16
+ [id] => 36
+ [name] => 项目26
+ [status] => wait
+ [end] => 2020-02-26
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 666
+ [project] => 36
+ [name] => 迭代566
+ [end] => 2020-02-26
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 8
+ [totalEstimate] => 4
+ [totalLeft] => 4
+ [totalReal] => 12
+ [progress] => 67
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 65
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 49
+ [program] => 4
+ [name] => 多分支产品49
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 145
+ [product] => 49
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 146
+ [product] => 49
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 147
+ [product] => 49
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 49
+ [id] => 59
+ [name] => 项目49
+ [status] => wait
+ [end] => 2019-01-22
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 68
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 49
+ [id] => 69
+ [name] => 项目59
+ [status] => doing
+ [end] => 2021-11-05
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [id] => 60
+ [program] => 4
+ [name] => 多分支产品60
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 60
+ [id] => 70
+ [name] => 项目60
+ [status] => doing
+ [end] => 2022-12-06
+ [execution] => stdClass Object
+ (
+ [id] => 700
+ [project] => 70
+ [name] => 阶段600
+ [end] => 2022-12-06
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 12
+ [totalEstimate] => 5
+ [totalLeft] => 0
+ [totalReal] => 12
+ [progress] => 100
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 60
+ [id] => 80
+ [name] => 项目70
+ [status] => doing
+ [end] => 2020-10-16
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 620
+ [project] => 80
+ [name] => 看板520
+ [end] => 2022-04-07
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 12
+ [totalEstimate] => 2
+ [totalLeft] => 2
+ [totalReal] => 14
+ [progress] => 86
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 73
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [4] => stdClass Object
+ (
+ [id] => 82
+ [program] => 4
+ [name] => 多平台产品82
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 244
+ [product] => 82
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 245
+ [product] => 82
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 246
+ [product] => 82
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 82
+ [id] => 12
+ [name] => 项目2
+ [status] => wait
+ [end] => 2020-02-02
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 642
+ [project] => 12
+ [name] => 迭代542
+ [end] => 2020-02-02
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 4
+ [totalEstimate] => 2
+ [totalLeft] => 2
+ [totalReal] => 6
+ [progress] => 67
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 51
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 82
+ [id] => 92
+ [name] => 项目82
+ [status] => wait
+ [end] => 2020-10-01
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 632
+ [project] => 92
+ [name] => 看板532
+ [end] => 2022-04-19
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 4
+ [totalEstimate] => 3
+ [totalLeft] => 3
+ [totalReal] => 7
+ [progress] => 57
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 43
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [5] => stdClass Object
+ (
+ [id] => 93
+ [program] => 4
+ [name] => 多平台产品93
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 93
+ [id] => 13
+ [name] => 项目3
+ [status] => doing
+ [end] => 2021-03-03
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 51
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 93
+ [id] => 23
+ [name] => 项目13
+ [status] => doing
+ [end] => 2019-01-13
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 56
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [others] => Array
+ (
+ [0] => stdClass Object
+ (
+ [name] => 项目集1
+ [products] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 2
+ [program] => 1
+ [name] => jack
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 2
+ [id] => 12
+ [name] => 项目2
+ [status] => wait
+ [end] => 2020-02-02
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 642
+ [project] => 12
+ [name] => 迭代542
+ [end] => 2020-02-02
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 4
+ [totalEstimate] => 2
+ [totalLeft] => 2
+ [totalReal] => 6
+ [progress] => 67
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 51
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 2
+ [id] => 22
+ [name] => 项目12
+ [status] => doing
+ [end] => 2022-12-12
+ [execution] => stdClass Object
+ (
+ [id] => 652
+ [project] => 22
+ [name] => 迭代552
+ [end] => 2022-12-12
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 4
+ [totalEstimate] => 1
+ [totalLeft] => 0
+ [totalReal] => 4
+ [progress] => 100
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 13
+ [program] => 1
+ [name] => jack
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 37
+ [product] => 13
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 38
+ [product] => 13
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 39
+ [product] => 13
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 13
+ [id] => 23
+ [name] => 项目13
+ [status] => doing
+ [end] => 2019-01-13
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 56
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 46
+ [program] => 1
+ [name] => 多分支产品46
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 136
+ [product] => 46
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 137
+ [product] => 46
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 138
+ [product] => 46
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 46
+ [id] => 56
+ [name] => 项目46
+ [status] => doing
+ [end] => 2020-10-19
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 686
+ [project] => 56
+ [name] => 阶段586
+ [end] => 2020-10-19
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 8
+ [totalEstimate] => 2
+ [totalLeft] => 2
+ [totalReal] => 10
+ [progress] => 80
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 67
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [id] => 57
+ [program] => 1
+ [name] => 多分支产品57
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 57
+ [id] => 67
+ [name] => 项目57
+ [status] => wait
+ [end] => 2019-09-03
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 70
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 57
+ [id] => 77
+ [name] => 项目67
+ [status] => doing
+ [end] => 2021-07-13
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 64
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [4] => stdClass Object
+ (
+ [id] => 90
+ [program] => 1
+ [name] => 多平台产品90
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 90
+ [id] => 20
+ [name] => 项目10
+ [status] => wait
+ [end] => 2020-10-10
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 650
+ [project] => 20
+ [name] => 迭代550
+ [end] => 2020-10-10
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 12
+ [totalEstimate] => 10
+ [totalLeft] => 10
+ [totalReal] => 22
+ [progress] => 55
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 68
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 90
+ [id] => 100
+ [name] => 项目90
+ [status] => wait
+ [end] => 2020-06-09
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 640
+ [project] => 100
+ [name] => 看板540
+ [end] => 2022-12-27
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 12
+ [totalEstimate] => 0
+ [totalLeft] => 0
+ [totalReal] => 12
+ [progress] => 100
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [name] => 项目集2
+ [products] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 3
+ [program] => 2
+ [name] => 正常产品3
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 3
+ [id] => 13
+ [name] => 项目3
+ [status] => doing
+ [end] => 2021-03-03
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 51
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 3
+ [id] => 23
+ [name] => 项目13
+ [status] => doing
+ [end] => 2019-01-13
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 56
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 14
+ [program] => 2
+ [name] => 正常产品14
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 40
+ [product] => 14
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 41
+ [product] => 14
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 42
+ [product] => 14
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 14
+ [id] => 24
+ [name] => 项目14
+ [status] => doing
+ [end] => 2020-02-14
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 654
+ [project] => 24
+ [name] => 迭代554
+ [end] => 2020-02-14
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 6
+ [totalEstimate] => 3
+ [totalLeft] => 3
+ [totalReal] => 9
+ [progress] => 67
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 55
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 47
+ [program] => 2
+ [name] => 多分支产品47
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 139
+ [product] => 47
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 140
+ [product] => 47
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 141
+ [product] => 47
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 47
+ [id] => 67
+ [name] => 项目57
+ [status] => wait
+ [end] => 2019-09-03
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 70
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [id] => 58
+ [program] => 2
+ [name] => 多分支产品58
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 58
+ [id] => 68
+ [name] => 项目58
+ [status] => wait
+ [end] => 2020-10-04
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 698
+ [project] => 68
+ [name] => 阶段598
+ [end] => 2020-10-04
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 10
+ [totalEstimate] => 3
+ [totalLeft] => 3
+ [totalReal] => 13
+ [progress] => 77
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 67
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 58
+ [id] => 78
+ [name] => 项目68
+ [status] => doing
+ [end] => 2022-08-14
+ [execution] => stdClass Object
+ (
+ [id] => 618
+ [project] => 78
+ [name] => 看板518
+ [end] => 2020-02-05
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 10
+ [totalEstimate] => 0
+ [totalLeft] => 0
+ [totalReal] => 10
+ [progress] => 100
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 71
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [4] => stdClass Object
+ (
+ [id] => 91
+ [program] => 2
+ [name] => 多平台产品91
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 91
+ [id] => 11
+ [name] => 项目1
+ [status] => wait
+ [end] => 2019-01-01
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 40
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 91
+ [id] => 21
+ [name] => 项目11
+ [status] => doing
+ [end] => 2021-11-11
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [name] => 项目集9
+ [products] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 10
+ [program] => 9
+ [name] => 正常产品10
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 28
+ [product] => 10
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 29
+ [product] => 10
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 30
+ [product] => 10
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 10
+ [id] => 20
+ [name] => 项目10
+ [status] => wait
+ [end] => 2020-10-10
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 650
+ [project] => 20
+ [name] => 迭代550
+ [end] => 2020-10-10
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 12
+ [totalEstimate] => 10
+ [totalLeft] => 10
+ [totalReal] => 22
+ [progress] => 55
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 68
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 10
+ [id] => 30
+ [name] => 项目20
+ [status] => doing
+ [end] => 2022-08-20
+ [execution] => stdClass Object
+ (
+ [id] => 660
+ [project] => 30
+ [name] => 迭代560
+ [end] => 2022-08-20
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 12
+ [totalEstimate] => 9
+ [totalLeft] => 9
+ [totalReal] => 21
+ [progress] => 57
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 66
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 43
+ [program] => 9
+ [name] => 多分支产品43
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 43
+ [id] => 53
+ [name] => 项目43
+ [status] => doing
+ [end] => 2021-07-16
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 47
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 43
+ [id] => 63
+ [name] => 项目53
+ [status] => doing
+ [end] => 2019-05-26
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 54
+ [program] => 9
+ [name] => 多分支产品54
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 54
+ [id] => 64
+ [name] => 项目54
+ [status] => doing
+ [end] => 2020-06-27
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 694
+ [project] => 64
+ [name] => 阶段594
+ [end] => 2020-06-27
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 6
+ [totalEstimate] => 10
+ [totalLeft] => 0
+ [totalReal] => 6
+ [progress] => 100
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [id] => 87
+ [program] => 9
+ [name] => 多平台产品87
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 259
+ [product] => 87
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 260
+ [product] => 87
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 261
+ [product] => 87
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ )
+
+ [4] => stdClass Object
+ (
+ [id] => 98
+ [program] => 9
+ [name] => 多平台产品98
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 292
+ [product] => 98
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 293
+ [product] => 98
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 294
+ [product] => 98
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 98
+ [id] => 28
+ [name] => 项目18
+ [status] => wait
+ [end] => 2020-06-18
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 658
+ [project] => 28
+ [name] => 迭代558
+ [end] => 2020-06-18
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 10
+ [totalEstimate] => 7
+ [totalLeft] => 0
+ [totalReal] => 10
+ [progress] => 100
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [name] => 项目集10
+ [products] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 11
+ [program] => 10
+ [name] => 正常产品11
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 31
+ [product] => 11
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 32
+ [product] => 11
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 33
+ [product] => 11
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 11
+ [id] => 21
+ [name] => 项目11
+ [status] => doing
+ [end] => 2021-11-11
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 11
+ [id] => 31
+ [name] => 项目21
+ [status] => doing
+ [end] => 2019-09-21
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 35
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 44
+ [program] => 10
+ [name] => 多分支产品44
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 44
+ [id] => 54
+ [name] => 项目44
+ [status] => doing
+ [end] => 2022-08-17
+ [execution] => stdClass Object
+ (
+ [id] => 684
+ [project] => 54
+ [name] => 阶段584
+ [end] => 2022-08-17
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 6
+ [totalEstimate] => 0
+ [totalLeft] => 0
+ [totalReal] => 6
+ [progress] => 100
+ )
+
+ )
+
+ [hours] => Array
+ (
+ [progress] => 55
+ )
+
+ )
+
+ [1] => stdClass Object
+ (
+ [product] => 44
+ [id] => 64
+ [name] => 项目54
+ [status] => doing
+ [end] => 2020-06-27
+ [delay] => 1
+ [execution] => stdClass Object
+ (
+ [id] => 694
+ [project] => 64
+ [name] => 阶段594
+ [end] => 2020-06-27
+ [hours] => stdClass Object
+ (
+ [totalConsumed] => 6
+ [totalEstimate] => 10
+ [totalLeft] => 0
+ [totalReal] => 6
+ [progress] => 100
+ )
+
+ [delay] => 1
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 55
+ [program] => 10
+ [name] => 多分支产品55
+ [plans] => Array
+ (
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 55
+ [id] => 75
+ [name] => 项目65
+ [status] => wait
+ [end] => 2019-05-11
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 100
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ [3] => stdClass Object
+ (
+ [id] => 88
+ [program] => 10
+ [name] => 多平台产品88
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 262
+ [product] => 88
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 263
+ [product] => 88
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 264
+ [product] => 88
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ )
+
+ [4] => stdClass Object
+ (
+ [id] => 99
+ [program] => 10
+ [name] => 多平台产品99
+ [plans] => Array
+ (
+ [0] => stdClass Object
+ (
+ [id] => 295
+ [product] => 99
+ [title] => 1.0
+ )
+
+ [1] => stdClass Object
+ (
+ [id] => 296
+ [product] => 99
+ [title] => 1.1
+ )
+
+ [2] => stdClass Object
+ (
+ [id] => 297
+ [product] => 99
+ [title] => 长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^!
+ )
+
+ )
+
+ [releases] => Array
+ (
+ )
+
+ [projects] => Array
+ (
+ [wait] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 99
+ [id] => 19
+ [name] => 项目9
+ [status] => wait
+ [end] => 2019-09-09
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 64
+ )
+
+ )
+
+ )
+
+ [doing] => Array
+ (
+ [0] => stdClass Object
+ (
+ [product] => 99
+ [id] => 29
+ [name] => 项目19
+ [status] => doing
+ [end] => 2021-07-19
+ [delay] => 1
+ [execution] => Array
+ (
+ )
+
+ [hours] => Array
+ (
+ [progress] => 68
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+ )
+
+)
+
\ No newline at end of file
diff --git a/test/model/program/move.sh b/test/model/program/move.sh
new file mode 100644
index 0000000000..83d843101e
--- /dev/null
+++ b/test/model/program/move.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+#This script is use to rename files
+for file in * ;
+do mv $file `echo $file | tr 'A-Z' 'a-z'`;
+done
diff --git a/test/model/project/checkhaschildren.php b/test/model/project/checkhaschildren.php
new file mode 100755
index 0000000000..d4fd3638b6
--- /dev/null
+++ b/test/model/project/checkhaschildren.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 1
+获取id为101的项目是否有子项目 >> 0
+
+*/
+
+$project = new Project('admin');
+
+$getID = array(1, 101);
+
+r($project->checkHasChildren($getID[0])) && p() && e('1'); //获取id为1的项目是否有子项目
+r($project->checkHasChildren($getID[1])) && p() && e('0'); //获取id为101的项目是否有子项目
\ No newline at end of file
diff --git a/test/model/project/checkhascontent.php b/test/model/project/checkhascontent.php
new file mode 100755
index 0000000000..2050494221
--- /dev/null
+++ b/test/model/project/checkhascontent.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+> 1
+查找是否存在父级或者所属项目为0的数据,若存在则为ture >> 1
+
+*/
+
+$project = $tester->loadModel('project');
+
+$unExistence = array(1, 0);
+
+r($project->checkHasContent($unExistence[0])) && p() && e('1'); // 查找是否存在父级或者所属项目为1的数据,若存在则为true
+r($project->checkHasContent($unExistence[1])) && p() && e('1'); // 查找是否存在父级或者所属项目为0的数据,若存在则为ture
\ No newline at end of file
diff --git a/test/model/project/getbudgetunitlist.php b/test/model/project/getbudgetunitlist.php
new file mode 100755
index 0000000000..31d6c0d020
--- /dev/null
+++ b/test/model/project/getbudgetunitlist.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+> 1
+
+*/
+
+$t = new Project('admin');
+/* GetBudgetUnitList(). */
+r($t->checkBudgetUnitList()) && p() && e('1'); //检查翻译
\ No newline at end of file
diff --git a/test/model/project/getbyid.php b/test/model/project/getbyid.php
new file mode 100755
index 0000000000..1aaae57c76
--- /dev/null
+++ b/test/model/project/getbyid.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+> project1,project
+获取不存在的项目 >> 0
+获取ID等于1的项目集 >> program1,program
+获取不存在的项目集 >> 0
+获取ID等于101的冲刺 >> project1,sprint
+获取不存在的冲刺 >> 0
+获取ID等于131的阶段 >> project31,stage
+获取不存在的阶段 >> 0
+获取ID等于161的阶段 >> project61,kanban
+获取不存在的看板 >> 0
+
+*/
+
+$t = new Project('admin');
+
+$getId = array(11, 0, 1, 0, 101, 0, 131, 0, 161, 0);
+
+r($t->getProjectByID($getId[0])) && p('code,type') && e('project1,project'); //获取ID等于11的项目
+r($t->getProjectByID($getId[1])) && p('code,type') && e('0'); //获取不存在的项目
+r($t->getProgramByID($getId[2])) && p('code,type') && e('program1,program'); //获取ID等于1的项目集
+r($t->getProgramByID($getId[3])) && p('code,type') && e('0'); //获取不存在的项目集
+r($t->getSprintByID($getId[4])) && p('code,type') && e('project1,sprint'); //获取ID等于101的冲刺
+r($t->getSprintByID($getId[5])) && p('code,type') && e('0'); //获取不存在的冲刺
+r($t->getStageByID($getId[6])) && p('code,type') && e('project31,stage'); //获取ID等于131的阶段
+r($t->getStageByID($getId[7])) && p('code,type') && e('0'); //获取不存在的阶段
+r($t->getKanbanByID($getId[8])) && p('code,type') && e('project61,kanban'); //获取ID等于161的阶段
+r($t->getKanbanByID($getId[9])) && p('code,type') && e('0'); //获取不存在的看板
\ No newline at end of file
diff --git a/test/model/project/getbyidlist.php b/test/model/project/getbyidlist.php
new file mode 100755
index 0000000000..025a1555bc
--- /dev/null
+++ b/test/model/project/getbyidlist.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+> 项目1;项目2;项目3
+
+*/
+
+$t = new Project('admin');
+
+$projectIdList = array(11,12,13);
+
+r(($t->getByIdList($projectIdList, 3))) && p('11:name;12:name;13:name') && e('项目1;项目2;项目3'); //获取projectIdList对应的项目名称
\ No newline at end of file
diff --git a/test/model/project/getdatabyproject.php b/test/model/project/getdatabyproject.php
new file mode 100755
index 0000000000..59c46ee40b
--- /dev/null
+++ b/test/model/project/getdatabyproject.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+> 129
+获取parent为11的首个项目的id >> 130
+获取parent为11的首个项目的id >> 131
+获取parent为10000的首个项目的id >> 0
+获取parent为131的首个版本的id >> 1
+获取parent为132的首个版本的id >> 6
+获取parent为10000的首个版本的id >> 0
+获取parent为132的首个发布的id >> 1
+获取parent为132的首个发布的id >> 6
+获取parent为10000的首个发布的id >> 0
+
+*/
+
+/* 还有case bug testtask doc表要写,暂时表中没数据 */
+
+$t = new Project('admin');
+
+$PID = array(39, 40, 'sprint', 41, 'stage', 10000, 131, 132, 10000, 131, 132, 10000);
+
+r($t->getExecutionData($PID[0])) && p('id') && e('129'); //获取parent为11首个项目的id
+r($t->getExecutionData($PID[1], $PID[2])) && p('id') && e('130'); //获取parent为11的首个项目的id
+r($t->getExecutionData($PID[3], $PID[4])) && p('id') && e('131'); //获取parent为11的首个项目的id
+r($t->getExecutionData($PID[5])) && p('id') && e('0'); //获取parent为10000的首个项目的id
+r($t->getBuildData($PID[6])) && p('id') && e('1'); //获取parent为131的首个版本的id
+r($t->getBuildData($PID[7])) && p('id') && e('6'); //获取parent为132的首个版本的id
+r($t->getBuildData($PID[8])) && p('id') && e('0'); //获取parent为10000的首个版本的id
+r($t->getReleaseData($PID[9])) && p('id') && e('1'); //获取parent为132的首个发布的id
+r($t->getReleaseData($PID[10])) && p('id') && e('6'); //获取parent为132的首个发布的id
+r($t->getReleaseData($PID[11])) && p('id') && e('0'); //获取parent为10000的首个发布的id
\ No newline at end of file
diff --git a/test/model/project/getinfolist.php b/test/model/project/getinfolist.php
new file mode 100755
index 0000000000..cfda53c84d
--- /dev/null
+++ b/test/model/project/getinfolist.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+> 0
+查询等待状态的项目 >> 项目1
+查询暂停状态的项目 >> 0
+查询关闭状态的项目 >> 0
+查询所有状态的项目 >> 项目1
+
+*/
+
+$project = new Project('admin');
+
+$t_status = array('doing', 'wait', 'suspended', 'closed', 'all');
+
+//var_dump($project->getInfoList('all'));die;
+r($project->getInfoList($t_status[0])) && p() && e('0'); //查询正在进行的项目
+r($project->getInfoList($t_status[1])) && p('11:name') && e('项目1'); //查询等待状态的项目
+r($project->getInfoList($t_status[2])) && p() && e('0'); //查询暂停状态的项目
+r($project->getInfoList($t_status[3])) && p() && e('0'); //查询关闭状态的项目
+r($project->getInfoList($t_status[4])) && p('11:name') && e('项目1'); //查询所有状态的项目
\ No newline at end of file
diff --git a/test/model/project/getoverviewlist.php b/test/model/project/getoverviewlist.php
new file mode 100755
index 0000000000..6004dea5ed
--- /dev/null
+++ b/test/model/project/getoverviewlist.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+> 15
+获取状态不为done和closed的项目 >> 15
+根据项目ID获取项目详情 >> 11
+获取不存在的项目 >> 0
+按照ID正序获取项目列表 >> 1
+按照项目名称倒序获取项目列表 >> 1
+
+*/
+
+$t = new Project('admin');
+
+$P_status = array('wait', 'undone', 11, 10000, 'id_asc', 'name_desc');
+
+r($t->getByStatus($P_status[0])) && p() && e('15'); // 获取未开始的项目
+r($t->getByStatus($P_status[1])) && p() && e('15'); // 获取状态不为done和closed的项目
+r($t->getByID($P_status[2])) && p('11:id') && e('11'); // 根据项目ID获取项目详情
+r($t->getByID($P_status[3])) && p('id') && e('0'); // 获取不存在的项目
+r($t->getListByOrder($P_status[4])) && p() && e('1'); //按照ID正序获取项目列表
+r($t->getListByOrder($P_status[5])) && p() && e('1'); // 按照项目名称倒序获取项目列表
\ No newline at end of file
diff --git a/test/model/project/getpairsbyidlist.php b/test/model/project/getpairsbyidlist.php
new file mode 100755
index 0000000000..1ecc019e2e
--- /dev/null
+++ b/test/model/project/getpairsbyidlist.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 3
+查找所有项目 >> 90
+
+*/
+
+$project = new Project('admin');
+
+$findProject = array(0,11,12,13);
+$findAllPro = array();
+
+r($project->getByIdListFind($findProject)) && p() && e('3'); //查找ID为0、11、12、13的项目
+r($project->getByIdListFind($findAllPro)) && p() && e('90'); //查找所有项目
\ No newline at end of file
diff --git a/test/model/project/getpairsbyprogram.php b/test/model/project/getpairsbyprogram.php
new file mode 100755
index 0000000000..c9bb509194
--- /dev/null
+++ b/test/model/project/getpairsbyprogram.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+> 90
+查找独立项目 >> No data.
+查找管理员可查看的所属项目集ID为1的项目 >> 9
+查找管理员可查看的所属项目集ID为1且状态为wait的项目 >> 3
+查找管理员可查看的所属项目集ID为1且状态不为closed的项目 >> 7
+
+*/
+
+/*
+ public function getListByOrder($orderBy)
+ {
+ $projects = $this->project->getPairsByProgram(3, 'doing', $orderBy);
+ return checkOrder($projects, $orderBy);
+ }
+}*/
+
+$t = new Project('admin');
+
+$t_project = array('', 0, 1, 'wait', 'noclosed');
+
+r($t->getByProgram($t_project[0])) && p() && e('90'); //查找管理员可查看的所有项目
+r($t->getByProgram($t_project[1])) && p() && e('No data.'); //查找独立项目
+r($t->getByProgram($t_project[2])) && p() && e('9'); //查找管理员可查看的所属项目集ID为1的项目
+r($t->getByStatusPairs($t_project[3])) && p() && e('3'); //查找管理员可查看的所属项目集ID为1且状态为wait的项目
+r($t->getByStatusPairs($t_project[4])) && p() && e('7'); //查找管理员可查看的所属项目集ID为1且状态不为closed的项目
\ No newline at end of file
diff --git a/test/model/project/getparentname.php b/test/model/project/getparentname.php
new file mode 100755
index 0000000000..796627e8be
--- /dev/null
+++ b/test/model/project/getparentname.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+> 项目集1
+获取id为1的项目父项目名字 >> 项目集1
+获取id为0的项目父项目名字 >> 0
+
+*/
+
+$project = new Project('admin');
+
+$getName = array(11, 1, 0);
+
+r($project->getParentName($getName[0])) && p('name') && e('项目集1'); //获取id为11的项目父项目名字
+r($project->getParentName($getName[1])) && p('name') && e('项目集1'); //获取id为1的项目父项目名字
+r($project->getParentName($getName[2])) && p('name') && e('0'); //获取id为0的项目父项目名字
\ No newline at end of file
diff --git a/test/model/project/getprojectsconsumed.php b/test/model/project/getprojectsconsumed.php
new file mode 100755
index 0000000000..9316dd3d84
--- /dev/null
+++ b/test/model/project/getprojectsconsumed.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getConsumed());die; >> 21.0
+ >> 28.0
+ >> 35.0
+
+*/
+
+$projects = new Project('admin');
+
+$getConsumed = array(11, 12, 13);
+
+//var_dump($projects->getConsumed($getConsumed));die;
+r($projects->getConsumed($getConsumed)) && p('11:totalConsumed') && e('21.0');
+r($projects->getConsumed($getConsumed)) && p('12:totalConsumed') && e('28.0');
+r($projects->getConsumed($getConsumed)) && p('13:totalConsumed') && e('35.0');
\ No newline at end of file
diff --git a/test/model/project/getstatdata.php b/test/model/project/getstatdata.php
new file mode 100755
index 0000000000..4776452a6b
--- /dev/null
+++ b/test/model/project/getstatdata.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+> 3
+任务数量 >> 13
+暂停数量 >> 2
+进行的数量 >> 2
+完成的数量 >> 0
+
+*/
+
+$project = new Project('admin');
+
+r($project->getStatData(13)) && p('bugCount') && e('3'); //统计id=13的项目bug数量
+r($project->getStatData(13)) && p('taskCount') && e('13'); //任务数量
+r($project->getStatData(13)) && p('waitCount') && e('2'); //暂停数量
+r($project->getStatData(13)) && p('doingCount') && e('2'); //进行的数量
+r($project->getStatData(13)) && p('finishedCount') && e('0'); //完成的数量
\ No newline at end of file
diff --git a/test/model/project/getstats.php b/test/model/project/getstats.php
new file mode 100755
index 0000000000..b182cee1b1
--- /dev/null
+++ b/test/model/project/getstats.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+> 630
+查看未完成的执行 >> 0
+查看所有进行中的执行 >> 315
+查看所有进行中的执行 >> 315
+查看id为11项目的执行 >> 7
+查看id为12项目的执行 >> 7
+
+*/
+
+$t = new Project('admin');
+
+$OpenImplement = array('all', 'undone', 'doing', 'wait', '11', '12');
+
+r($t->getByStatusExe($OpenImplement[0])) && p() && e('630'); //查看所有执行
+r($t->getByStatusExe($OpenImplement[1])) && p() && e('0'); //查看未完成的执行
+r($t->getByStatusExe($OpenImplement[2])) && p() && e('315'); //查看所有进行中的执行
+r($t->getByStatusExe($OpenImplement[3])) && p() && e('315'); //查看所有进行中的执行
+r($t->getByProject($OpenImplement[4])) && p() && e('7'); //查看id为11项目的执行
+r($t->getByProject($OpenImplement[5])) && p() && e('7'); //查看id为12项目的执行
\ No newline at end of file
diff --git a/test/model/project/getswitcher.php b/test/model/project/getswitcher.php
new file mode 100755
index 0000000000..1c11660186
--- /dev/null
+++ b/test/model/project/getswitcher.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+> 0
+获取项目ID为11的迭代列表页面的项目下拉菜单,查看是否包含项目ID为11的名称 >> 项目1
+
+*/
+
+$project = $tester->loadModel('project');
+
+//var_dump($project->getSwitcher(11, 'project', 'browse'));die;
+r($project->getSwitcher(11, 'project', 'browse')) && p() && e('0'); //获取项目下拉菜单,项目列表页面没有项目下拉菜单
+r($project->getSwitcher(11, 'project', 'execution')) && p() && e("项目1"); //获取项目ID为11的迭代列表页面的项目下拉菜单,查看是否包含项目ID为11的名称
\ No newline at end of file
diff --git a/test/model/project/getteammemberpairs.php b/test/model/project/getteammemberpairs.php
new file mode 100755
index 0000000000..8b28fa1bcd
--- /dev/null
+++ b/test/model/project/getteammemberpairs.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 2
+获取id为1的项目团队成员个数 >> 0
+
+*/
+
+$project = new Project('admin');
+
+$getIdNub = array(11, 1);
+
+r($project->getTeamMemberPairs($getIdNub[0])) && p() && e('2'); //获取id为11的项目团队成员个数
+r($project->getTeamMemberPairs($getIdNub[1])) && p() && e('0'); //获取id为1的项目团队成员个数
\ No newline at end of file
diff --git a/test/model/project/getteammembers.php b/test/model/project/getteammembers.php
new file mode 100755
index 0000000000..17f52ad4a0
--- /dev/null
+++ b/test/model/project/getteammembers.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 2
+获取id为11的项目团队成员个数,开启新手引导 >> 1
+
+*/
+
+$project = new Project('admin');
+
+$getNu = array(11, array('admin', 'pm92'), 11, array('admin'), true);
+
+r($project->getTeamMembers($getNu[0], $getNu[1])) && p() && e('2'); //获取id为11的项目团队成员个数
+r($project->getTeamMembers($getNu[2], $getNu[3], $getNu[4])) && p() && e('1'); //获取id为11的项目团队成员个数,开启新手引导
\ No newline at end of file
diff --git a/test/model/project/gettotalbugbyproject.php b/test/model/project/gettotalbugbyproject.php
new file mode 100755
index 0000000000..38f95e1f4d
--- /dev/null
+++ b/test/model/project/gettotalbugbyproject.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 3
+
+*/
+
+$project = new Project('admin');
+
+$getBug = array(11, 12, 13, 14, 15, 16, 27);
+
+//var_dump($project->getTotalBugBy($getBug, 'active'));die;
+
+r($project->getTotalBugBy($getBug, 'active')) && p(11) && e('3'); //状态一致时正常打印id为11的项目bug数量
+r($project->getTotalBugBy($getBug, 'active')) && p(27) && e(''); //在状态status不一致的情况下,打印id为27的项目bug数量
\ No newline at end of file
diff --git a/test/model/project/gettotalstoriesbyproject.php b/test/model/project/gettotalstoriesbyproject.php
new file mode 100755
index 0000000000..a3ddfc3e9b
--- /dev/null
+++ b/test/model/project/gettotalstoriesbyproject.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getTotalStoriesByProject());die;
\ No newline at end of file
diff --git a/test/model/project/getworkhour.php b/test/model/project/getworkhour.php
new file mode 100755
index 0000000000..4afdd17e5e
--- /dev/null
+++ b/test/model/project/getworkhour.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+> 61.0
+消耗95.0小时 >> 95.0
+
+*/
+
+$project = new Project('admin');
+
+r($project->getWorkHour(13)) && p('totalEstimate') && e('61.0'); //预计61.0小时
+r($project->getWorkHour(13)) && p('totalConsumed') && e('95.0'); //消耗95.0小时
+r($project->getWorkHour(1000)) && p('totalEstimate') && e(''); //测试不存在的项目
\ No newline at end of file
diff --git a/test/model/project/isclickable.php b/test/model/project/isclickable.php
new file mode 100755
index 0000000000..f1ceff7bf8
--- /dev/null
+++ b/test/model/project/isclickable.php
@@ -0,0 +1,61 @@
+#!/usr/bin/env php
+> 1
+检查未开始项目的完成按钮 >> 1
+检查未开始项目的关闭按钮 >> 1
+检查未开始项目的暂停按钮 >> 1
+检查未开始项目的激活按钮 >> 0
+检查进行中项目的开始按钮 >> 0
+检查进行中项目的完成按钮 >> 1
+检查进行中项目的关闭按钮 >> 1
+检查进行中项目的暂停按钮 >> 1
+检查进行中项目的激活按钮 >> 0
+检查已暂停项目的开始按钮 >> 1
+检查已暂停项目的完成按钮 >> 0
+检查已暂停项目的关闭按钮 >> 1
+检查已暂停项目的暂停按钮 >> 0
+检查已暂停项目的激活按钮 >> 0
+检查已关闭项目的开始按钮 >> 0
+检查已关闭项目的完成按钮 >> 0
+检查已关闭项目的关闭按钮 >> 0
+检查已关闭项目的暂停按钮 >> 0
+检查已关闭项目的激活按钮 >> 1
+
+*/
+
+$projectModel = $tester->loadModel('project');
+
+$waitProject = $projectModel->getByID(11);
+$doingProject = $projectModel->getByID(13);
+$suspendProject = $projectModel->getByID(17);
+$closedProject = $projectModel->getByID(18);
+$status = array('start', 'finish', 'close', 'suspend', 'activate', );
+
+r($projectModel->isClickable($waitProject, $status[0])) && p() && e('1'); // 检查未开始项目的开始按钮
+r($projectModel->isClickable($waitProject, $status[1])) && p() && e('1'); // 检查未开始项目的完成按钮
+r($projectModel->isClickable($waitProject, $status[2])) && p() && e('1'); // 检查未开始项目的关闭按钮
+r($projectModel->isClickable($waitProject, $status[3])) && p() && e('1'); // 检查未开始项目的暂停按钮
+r($projectModel->isClickable($waitProject, $status[4])) && p() && e('0'); // 检查未开始项目的激活按钮
+r($projectModel->isClickable($doingProject, $status[0])) && p() && e('0'); // 检查进行中项目的开始按钮
+r($projectModel->isClickable($doingProject, $status[1])) && p() && e('1'); // 检查进行中项目的完成按钮
+r($projectModel->isClickable($doingProject, $status[2])) && p() && e('1'); // 检查进行中项目的关闭按钮
+r($projectModel->isClickable($doingProject, $status[3])) && p() && e('1'); // 检查进行中项目的暂停按钮
+r($projectModel->isClickable($doingProject, $status[4])) && p() && e('0'); // 检查进行中项目的激活按钮
+r($projectModel->isClickable($suspendProject, $status[0])) && p() && e('1'); // 检查已暂停项目的开始按钮
+r($projectModel->isClickable($suspendProject, $status[1])) && p() && e('0'); // 检查已暂停项目的完成按钮
+r($projectModel->isClickable($suspendProject, $status[2])) && p() && e('1'); // 检查已暂停项目的关闭按钮
+r($projectModel->isClickable($suspendProject, $status[3])) && p() && e('0'); // 检查已暂停项目的暂停按钮
+r($projectModel->isClickable($suspendProject, $status[4])) && p() && e('0'); // 检查已暂停项目的激活按钮
+r($projectModel->isClickable($closedProject, $status[0])) && p() && e('0'); // 检查已关闭项目的开始按钮
+r($projectModel->isClickable($closedProject, $status[1])) && p() && e('0'); // 检查已关闭项目的完成按钮
+r($projectModel->isClickable($closedProject, $status[2])) && p() && e('0'); // 检查已关闭项目的关闭按钮
+r($projectModel->isClickable($closedProject, $status[3])) && p() && e('0'); // 检查已关闭项目的暂停按钮
+r($projectModel->isClickable($closedProject, $status[4])) && p() && e('1'); // 检查已关闭项目的激活按钮
\ No newline at end of file
diff --git a/test/model/project/move.sh b/test/model/project/move.sh
new file mode 100644
index 0000000000..83d843101e
--- /dev/null
+++ b/test/model/project/move.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+#This script is use to rename files
+for file in * ;
+do mv $file `echo $file | tr 'A-Z' 'a-z'`;
+done
diff --git a/test/model/project/savestate.php b/test/model/project/savestate.php
new file mode 100755
index 0000000000..0d6f754791
--- /dev/null
+++ b/test/model/project/savestate.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 14
+传入存在ID的值99,保存session,返回第一位默认值11 >> 11
+
+*/
+
+$project = new Project('dev1');
+
+$projectId = array(14, 99);
+
+r($project->saveState($projectId[0])) && p() && e('14'); //传入存在ID的值14,保存session,返回对应值14
+r($project->saveState($projectId[1])) && p() && e('11'); //传入存在ID的值99,保存session,返回第一位默认值11
\ No newline at end of file
diff --git a/test/runtime.zip b/test/runtime.zip
new file mode 100644
index 0000000000..26675d9438
Binary files /dev/null and b/test/runtime.zip differ