<?php
declare(strict_types=1);
namespace {$repo=$argv[2]??dirname(__DIR__,2);require $repo.'/vendor/autoload.php';}
namespace think\facade {class Db {public static $dm=true;public static function connect(){return self::$dm?new \app\common\database\Dm:new \stdClass;}}}
namespace app\common\database {class Dm {}}
namespace app\common\service {class BaseService {}}
namespace app\admin\model {class Store {public static function getAllData($where,$field){if($where!==['is_delete'=>0]||$field!=='store_id,store_name')throw new \RuntimeException('Store projection contract changed');return [];}}}
namespace app\common\model {class Equipment extends \think\Model {protected $autoWriteTimestamp=false;protected $schema=['id'=>'int','code'=>'string','name'=>'string','type'=>'int','matecode'=>'string','mate_flag'=>'int','mate_time'=>'string','status'=>'int','store_id'=>'int','is_delete'=>'int','create_by'=>'string','create_time'=>'string','update_time'=>'string','nested'=>'json'];public static $row=[];public static $where;public static function detail($id){return $id?new self(self::$row):null;}public static function getList($where,$field='*'){self::$where=$where;return ['total'=>1,'per_page'=>15,'current_page'=>1,'last_page'=>1,'data'=>[(new self(self::$row))->toArray()]];}}}
namespace app\admin\controller {class Controller {public $request;public function __construct(array $p=[]){$this->request=new class($p){private $p;public function __construct($p){$this->p=$p;}public function param(){return $this->p;}};}protected function renderSuccess($data=[],string $message='success'):\think\response\Json{return new \think\response\Json(new \think\Cookie(new \think\Request()),['status'=>200,'message'=>$message,'data'=>$data,'trace_id'=>'123456789abcd']);}}}
namespace {require $repo.'/app/common/enum/EnumBasics.php';require $repo.'/app/common/enum/equipment/EquipmentType.php';require $argv[1]??$repo.'/app/admin/service/store/Equipment.php';require $repo.'/app/admin/controller/store/Equipment.php';$n=0;$assert=static function($ok,$why)use(&$n){$n++;if(!$ok)throw new \RuntimeException($why);};$base=['id'=>23,'code'=>"user.order ' literal 中文",'name'=>'same bytes','type'=>60,'matecode'=>'!NO_PAIR_SYNTHETIC!','mate_flag'=>1,'mate_time'=>'2000-01-01 00:00:00.000000','status'=>0,'store_id'=>2147001113,'is_delete'=>0,'create_by'=>'TEST','create_time'=>'2026-10-11 02:00:00','update_time'=>'2026-10-11 02:00:00'];$service=new \app\admin\service\store\Equipment;
foreach([true,false] as $dm){\think\facade\Db::$dm=$dm;foreach(['2000-01-01 00:00:00.000000','2026-10-11 02:03:04.0','2026-10-11 02:03:04.000','2000-01-01 00:00:00','2000-01-01 00:00:00.000001','2000-01-01 00:00:00.0000000','not a datetime',null,123,'2024-02-29 23:59:59.0','2026-02-29 00:00:00.0','2024-02-30 00:00:00.0','2024-01-01 24:00:00.0','0999-01-01 00:00:00.0'] as $date){$row=$base;$row['mate_time']=$date;\app\common\model\Equipment::$row=$row;$modelArray=(new \app\common\model\Equipment($row))->toArray();$expected=$modelArray;$canonical=['2000-01-01 00:00:00.000000'=>'2000-01-01 00:00:00','2026-10-11 02:03:04.0'=>'2026-10-11 02:03:04','2026-10-11 02:03:04.000'=>'2026-10-11 02:03:04','2024-02-29 23:59:59.0'=>'2024-02-29 23:59:59'];if($dm&&is_string($date)&&array_key_exists($date,$canonical))$expected['mate_time']=$canonical[$date];$detail=$service->detail(23);$target=$expected+['type_name'=>'咖啡机','store_name'=>''];$assert($detail===$target,'DM/MySQL actual Service detail full row date='.var_export($date,true));$list=$service->getList(['type'=>60]);$assert($list===['total'=>1,'per_page'=>15,'current_page'=>1,'last_page'=>1,'data'=>[$expected+['type_name'=>'咖啡机']]],'Actual Service list all row keys/types preserved');$assert(\app\common\model\Equipment::$where===[['is_delete','=',0],['type','=',60]],'Source filters exactly same');$controller=new \app\admin\controller\store\Equipment(['type'=>60]);$wire=json_decode($controller->detail(23)->getContent(),true);$assert($wire===['status'=>200,'message'=>'success','data'=>['detail'=>$target],'trace_id'=>'123456789abcd'],'Actual Controller+Json detail serialization');$wire=json_decode($controller->lists()->getContent(),true);$assert($wire['data']['list']===$list&&$wire['message']==='success'&&$wire['status']===200,'Actual Controller+Json list serialization');}}
\think\facade\Db::$dm=true;$assert($service->detail(0)===[],'Missing detail original branch');$controller=new \app\admin\controller\store\Equipment;$assert(json_decode($controller->detail(0)->getContent(),true)['data']===['detail'=>[]],'Missing Controller detail preserved');$reflection=new \ReflectionClass($service);if($reflection->hasMethod('readonlyResponseRow')){$method=$reflection->getMethod('readonlyResponseRow');$method->setAccessible(true);$assert($method->invoke($service,['other'=>'bytes','create_time'=>'x.000000'])===['other'=>'bytes','create_time'=>'x.000000'],'Missing mate_time and other dates untouched');$assert($method->invoke($service,['mate_time'=>null,'nested'=>['mate_time'=>'x.000000']])===['mate_time'=>null,'nested'=>['mate_time'=>'x.000000']],'Null and nested content untouched');}else throw new \RuntimeException('Original service lacks narrow response gate');echo json_encode(['assertions'=>$n,'actual_Service_methods'=>2,'actual_Controller_methods'=>2,'real_ThinkPHP_Model_toArray_and_Json'=>true,'explicit_static_DB_dependencies_stubbed'=>true,'PDO'=>0,'SQL'=>0,'passed'=>true]),"\n";}
