<?php
declare(strict_types=1);$base=$argv[1]??'';$candidate=$argv[2]??$base;define('TP_ENV','poc');define('BUSINESS','aizhct');define('ENTERPRISE_NO','10001');require $base.'/vendor/autoload.php';spl_autoload_register(static function($c)use($base,$candidate){foreach(['app\\'=>'app/','cores\\'=>'cores/'] as $p=>$d)if(strpos($c,$p)===0){$r=$d.str_replace('\\','/',substr($c,strlen($p))).'.php';$f=is_file($candidate.'/'.$r)?$candidate.'/'.$r:$base.'/'.$r;if(is_file($f))require $f;}},true,true);
trait NoMoneyIO {public static $IO=0;public function getFields(string $table):array{$t=preg_replace('/^yoshop_/','',trim(explode(' ',$table)[0],'`"'));$m=json_decode(file_get_contents(__DIR__.'/structure-B.json'),true)['tables'][$t]['columns']??[];$out=[];foreach($m as $c)$out[$c['column_name']]=['name'=>$c['column_name'],'type'=>$c['column_type'],'notnull'=>$c['is_nullable']==='NO','default'=>$c['column_default'],'primary'=>$c['extra']==='auto_increment','autoinc'=>$c['extra']==='auto_increment'];return $out;}public function getPDOStatement(string $sql,array $bind=[],bool $master=false,bool $procedure=false):PDOStatement{self::$IO++;throw new RuntimeException('No response-only SQL or write allowed');}protected function createPdo($a,$b,$c,$d){self::$IO++;throw new RuntimeException('No PDO allowed');}}
class MoneyMysql extends \think\db\connector\Mysql {use NoMoneyIO;public function getBuilderClass():string{return \think\db\builder\Mysql::class;}}
class MoneyDm extends \app\common\database\Dm {use NoMoneyIO;}
$app=new \think\App($base);$app->setEnvName('poc');$app->setRuntimePath(__DIR__.'/private/money-contract-runtime/');$app->initialize();\think\App::$store_id=2147001111;$cfg=$app->config->get('database');$mysql=$cfg['connections']['mysql'];$mysql['type']='\\MoneyMysql';$dm=$mysql;$dm['type']='\\MoneyDm';$cfg['connections']=['mysql'=>$mysql,'dm'=>$dm];$checks=0;$fail=[];
$must=static function($ok,$name)use(&$checks,&$fail){$checks++;if(!$ok)$fail[]=$name;};$fields=['balance','withdrawable_balance','activity_principal_balance','subsidy_balance','gift_balance','pay_money','expend_money'];
$values=[[0,'0.00'],[0.1,'0.10'],[-1.25,'-1.25'],[12.3,'12.30'],[99999999.99,'99999999.99'],[null,null],['bad','bad'],['0.00','0.00'],['1.20','1.20'],['1e2','1e2'],[0.001,0.001],[999999999.99,999999999.99],[INF,INF]];
foreach(['mysql','dm'] as $engine){$cfg['default']=$engine==='mysql'?'dm':'mysql';$app->config->set($cfg,'database');$app->db->setConfig($app->config);$app->db->connect('mysql',true);$app->db->connect('dm',true);foreach(['app\\common\\model\\User','app\\store\\model\\User','app\\terminal\\model\\User','app\\common\\model\\user\\BalanceLog','app\\store\\model\\user\\BalanceLog','app\\terminal\\model\\user\\BalanceLog'] as $class){$names=strpos($class,'BalanceLog')!==false?['money','balance_after']:$fields;foreach($names as $name)foreach($values as $i=>$pair){[$value,$expected]=$pair;$row=[$name=>$value,'sentinel'=>'unchanged','other_number'=>0.123];$model=(new $class($row))->setConnection($engine);$before=serialize($model->getData());$out=$model->toArray();$want=$row;$want[$name]=$engine==='dm'?$expected:$value;$label=$engine.'/'.$class.'/'.$name.'/'.$i;$must($out===$want,$label.':DTO');$must(serialize($model->getData())===$before,$label.':raw_model_unmodified');$must($model->getConnection()===$engine,$label.':explicit_model_connection');if(!is_float($value)||is_finite($value))$must(json($out)->getContent()===json_encode($want,JSON_UNESCAPED_UNICODE),$label.':actual_Json');}
 $empty=(new $class(['sentinel'=>'unchanged']))->setConnection($engine);$must($empty->toArray()===['sentinel'=>'unchanged'],$engine.'/'.$class.':missing_fields_not_added');}
 $u=(new \app\store\model\User(['balance'=>0.1,'pay_money'=>12.3]))->setConnection($engine);$log=(new \app\store\model\user\PointsLog(['value'=>0]))->setConnection($engine);$log->setRelation('user',$u);$row=$log->toArray();$must($row['user']===['balance'=>$engine==='dm'?'0.10':0.1,'pay_money'=>$engine==='dm'?'12.30':12.3],$engine.':nested_user_actual_relation');$must($u->getData()===['balance'=>0.1,'pay_money'=>12.3],$engine.':nested_raw_user_unmodified');}
$must(MoneyMysql::$IO===0&&MoneyDm::$IO===0,'no_SQL_PDO_hook_side_effect');echo json_encode(['assertions'=>$checks,'failures'=>$fail,'actual_models'=>6,'Json'=>true,'explicit_model_connection_vs_opposite_default'=>true,'SQL'=>0,'PDO'=>0,'HTTP'=>0,'DML'=>0]),"\n";exit($fail?1:0);
