f = $this->get_inst_om_application(); $this->edition = $this->f->get_inst__om_edition(); } public function tearDown(): void { $this->f->__destruct(); parent::common_tearDown(); parent::tearDown(); } public function onNotSuccessfulTest(Throwable $e): void { parent::common_onNotSuccessfulTest($e); parent::onNotSuccessfulTest($e); } // ----------------------------------------------------------------------------- /** * @group generation */ function test_gen_files_contain_columns_attributes() { $gen_path = realpath(__DIR__.'/../core/gen/obj'); $this->assertNotFalse($gen_path, 'Le répertoire core/gen/obj n\'existe pas'); $files = glob($gen_path.'/*.class.php'); $this->assertNotEmpty($files, 'Aucun fichier gen trouvé dans '.$gen_path); foreach ($files as $file) { $basename = basename($file, '.class.php'); $class_name = $basename.'_gen'; require_once $file; $this->assertTrue( class_exists($class_name, false), $basename.' : la classe '.$class_name.' n\'existe pas' ); $ref = new ReflectionClass($class_name); $this->assertTrue( $ref->hasConstant('COLUMNS_ATTRIBUTES'), $basename.' ne contient pas la constante COLUMNS_ATTRIBUTES' ); $const_ref = $ref->getReflectionConstant('COLUMNS_ATTRIBUTES'); $this->assertTrue( $const_ref->isProtected(), $basename.' : COLUMNS_ATTRIBUTES devrait être protected' ); $value = $const_ref->getValue(); $this->assertIsArray($value, $basename.' : COLUMNS_ATTRIBUTES n\'est pas un array'); $this->assertNotEmpty($value, $basename.' : COLUMNS_ATTRIBUTES est vide'); foreach ($value as $col_name => $col_info) { $prefix = $basename.' : COLUMNS_ATTRIBUTES["'.$col_name.'"]'; $this->assertArrayHasKey('name', $col_info, $prefix.' manque la clé "name"'); $this->assertArrayHasKey('type', $col_info, $prefix.' manque la clé "type"'); $this->assertArrayHasKey('len', $col_info, $prefix.' manque la clé "len"'); $this->assertArrayHasKey('flags', $col_info, $prefix.' manque la clé "flags"'); $this->assertIsArray($col_info['flags'], $prefix.' : "flags" devrait être un array'); } } } /** * @group regression */ function test_mode_ajout_nombre_de_colonnes_coherent() { // On initialise un objet au hasard $obj = $this->f->get_inst__om_dbform(array( "obj" => "om_requete", "idx" => "]", )); // Vérifier que tous les éléments décrivant les colonnes // contiennent bien le même nombre de colonnes $nb_colonnes = count($obj->champs); $this->assertCount($nb_colonnes, $obj->longueurMax); $this->assertCount($nb_colonnes, $obj->type); $this->assertCount($nb_colonnes, $obj->flags); $this->assertCount($nb_colonnes, $obj->val); } // ========================================================================= // Tests de extract_alias_from_expression // ========================================================================= /** * Appelle la méthode protégée extract_alias_from_expression via * ReflectionMethod pour pouvoir la tester unitairement. */ private function call_extract_alias($expr) { $obj = $this->f->get_inst__om_dbform(array( "obj" => "om_requete", "idx" => "]", )); $method = new ReflectionMethod($obj, 'extract_alias_from_expression'); $method->setAccessible(true); return $method->invoke($obj, $expr); } // --- Cas basiques -------------------------------------------------------- function test_extract_alias__simple_as_majuscule() { $this->assertSame('alias', $this->call_extract_alias('column AS alias')); } function test_extract_alias__simple_as_minuscule() { $this->assertSame('alias', $this->call_extract_alias('column as alias')); } function test_extract_alias__as_casse_mixte() { $this->assertSame('alias', $this->call_extract_alias('column As alias')); $this->assertSame('alias', $this->call_extract_alias('column aS alias')); } // --- Absence d'alias → null ---------------------------------------------- function test_extract_alias__sans_as_retourne_null() { $this->assertNull($this->call_extract_alias('column')); } function test_extract_alias__chaine_vide_retourne_null() { $this->assertNull($this->call_extract_alias('')); } // --- AS faisant partie d'un autre mot → ne doit PAS matcher -------------- function test_extract_alias__as_dans_mot_database() { $this->assertNull($this->call_extract_alias('database')); } function test_extract_alias__as_dans_mot_cases() { $this->assertNull($this->call_extract_alias('cases')); } function test_extract_alias__as_dans_mot_last() { $this->assertNull($this->call_extract_alias('last')); } function test_extract_alias__as_dans_mot_has_value() { $this->assertNull($this->call_extract_alias('has_value')); } function test_extract_alias__as_dans_mot_vase() { $this->assertNull($this->call_extract_alias('vase')); } function test_extract_alias__as_prefixe_mot_asset() { $this->assertNull($this->call_extract_alias('asset')); } function test_extract_alias__as_suffixe_mot_atlas() { $this->assertNull($this->call_extract_alias('atlas')); } // --- Parenthèses : AS à l'intérieur ignoré ------------------------------- function test_extract_alias__as_dans_parentheses_ignore() { $this->assertSame( 'alias', $this->call_extract_alias('(CASE WHEN x THEN y END) AS alias') ); } function test_extract_alias__fonction_concat_as() { $this->assertSame( 'full_name', $this->call_extract_alias('CONCAT(a, b) AS full_name') ); } function test_extract_alias__sous_requete_as_interne_ignore() { $this->assertSame( 'col', $this->call_extract_alias('(SELECT name AS n FROM t) AS col') ); } function test_extract_alias__parentheses_imbriquees() { $this->assertSame( 'result', $this->call_extract_alias('((x AS y)) AS result') ); } function test_extract_alias__uniquement_as_dans_parentheses_retourne_null() { $this->assertNull( $this->call_extract_alias('(something AS inner)') ); } // --- Chaînes : AS à l'intérieur de quotes ignoré ------------------------- function test_extract_alias__as_dans_guillemets_simples_ignore() { $this->assertSame( 'alias', $this->call_extract_alias("'text AS other' AS alias") ); } function test_extract_alias__as_dans_guillemets_doubles_ignore() { $this->assertSame( 'alias', $this->call_extract_alias('"text AS other" AS alias') ); } function test_extract_alias__uniquement_as_dans_guillemets_simples_retourne_null() { $this->assertNull( $this->call_extract_alias("'value AS other'") ); } function test_extract_alias__uniquement_as_dans_guillemets_doubles_retourne_null() { $this->assertNull( $this->call_extract_alias('"value AS other"') ); } // --- Alias entre quotes -------------------------------------------------- function test_extract_alias__alias_entre_guillemets_doubles() { $this->assertSame( 'my_alias', $this->call_extract_alias('column AS "my_alias"') ); } function test_extract_alias__alias_entre_guillemets_simples() { $this->assertSame( 'my_alias', $this->call_extract_alias("column AS 'my_alias'") ); } // --- Dernier AS qui gagne (multiple AS au niveau supérieur) --------------- function test_extract_alias__multiple_as_top_level_dernier_gagne() { $this->assertSame('c', $this->call_extract_alias('a AS b AS c')); } // --- Alias avec underscores et chiffres ---------------------------------- function test_extract_alias__alias_avec_underscores() { $this->assertSame( 'my_long_alias_name', $this->call_extract_alias('column AS my_long_alias_name') ); } function test_extract_alias__alias_avec_chiffres() { $this->assertSame('col1', $this->call_extract_alias('column AS col1')); } // --- Espaces multiples --------------------------------------------------- function test_extract_alias__espaces_multiples_autour_du_as() { $this->assertSame( 'alias', $this->call_extract_alias('column AS alias') ); } // --- AS en début d'expression -------------------------------------------- function test_extract_alias__as_en_debut_expression() { $this->assertSame('alias', $this->call_extract_alias('AS alias')); } // --- AS sans identifiant après → null ------------------------------------ function test_extract_alias__as_en_fin_sans_alias_retourne_null() { $this->assertNull($this->call_extract_alias('column AS ')); } function test_extract_alias__as_seul_retourne_null() { $this->assertNull($this->call_extract_alias('AS')); } // --- Expressions SQL réalistes ------------------------------------------- function test_extract_alias__expression_case_when() { $this->assertSame( 'statut', $this->call_extract_alias( "CASE WHEN status = 'A' THEN 'Actif' ELSE 'Inactif' END AS statut" ) ); } function test_extract_alias__expression_cast() { $this->assertSame( 'montant_txt', $this->call_extract_alias('CAST(montant AS TEXT) AS montant_txt') ); } function test_extract_alias__expression_table_point_colonne() { $this->assertSame( 'nom', $this->call_extract_alias('t.nom_complet AS nom') ); } function test_extract_alias__expression_calcul_arithmetique() { $this->assertSame( 'total', $this->call_extract_alias('prix * quantite AS total') ); } function test_extract_alias__sous_requete_complete() { $this->assertSame( 'nb', $this->call_extract_alias( '(SELECT COUNT(*) FROM detail AS d WHERE d.id = master.id) AS nb' ) ); } function test_extract_alias__coalesce_avec_as() { $this->assertSame( 'valeur', $this->call_extract_alias("COALESCE(a, 'N/A') AS valeur") ); } // --- AS collé à des opérateurs (pas de lettre/chiffre/underscore avant/après) function test_extract_alias__as_apres_parenthese_fermante() { $this->assertSame( 'res', $this->call_extract_alias('(a + b)AS res') ); } function test_extract_alias__as_suivi_guillemet_double() { $this->assertSame( 'res', $this->call_extract_alias('col AS"res"') ); } }