feat(core): create investigation node
This commit is contained in:
parent
b1f931d8f2
commit
1686194c1a
6 changed files with 443 additions and 0 deletions
184
docs/tickets/closed/TICKET-007.md
Normal file
184
docs/tickets/closed/TICKET-007.md
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
# Ticket #007
|
||||
|
||||
## Titre
|
||||
|
||||
Créer le module `InvestigationNode`.
|
||||
|
||||
---
|
||||
|
||||
## Objectif
|
||||
|
||||
Créer une structure métier représentant un élément de l'arborescence d'une enquête.
|
||||
|
||||
Un nœud peut représenter :
|
||||
|
||||
- un dossier ;
|
||||
- un fichier.
|
||||
|
||||
Ce module servira de base au futur modèle d'arborescence.
|
||||
|
||||
---
|
||||
|
||||
## Responsabilités
|
||||
|
||||
Le module `InvestigationNode` doit :
|
||||
|
||||
- mémoriser le nom d'un élément ;
|
||||
- mémoriser son type ;
|
||||
- gérer sa propre mémoire ;
|
||||
- exposer ses informations en lecture seule.
|
||||
|
||||
---
|
||||
|
||||
## Hors périmètre
|
||||
|
||||
Ce ticket ne doit pas :
|
||||
|
||||
- parcourir le système de fichiers ;
|
||||
- construire une arborescence complète ;
|
||||
- stocker des enfants ;
|
||||
- afficher quoi que ce soit avec GTK ;
|
||||
- communiquer avec SQLite ;
|
||||
- ouvrir une enquête.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
InvestigationTreeModel
|
||||
│
|
||||
└── InvestigationNode
|
||||
```
|
||||
|
||||
Le module appartient à la couche `core`.
|
||||
|
||||
Il ne doit contenir aucune dépendance vers GTK.
|
||||
|
||||
---
|
||||
|
||||
## Fichiers concernés
|
||||
|
||||
```text
|
||||
include/core/investigation_node.h
|
||||
src/core/investigation_node.c
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Type attendu
|
||||
|
||||
```c
|
||||
typedef enum
|
||||
{
|
||||
INVESTIGATION_NODE_DIRECTORY,
|
||||
INVESTIGATION_NODE_FILE
|
||||
} InvestigationNodeType;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interface publique attendue
|
||||
|
||||
```c
|
||||
InvestigationNode *investigation_node_new(
|
||||
const char *name,
|
||||
InvestigationNodeType type
|
||||
);
|
||||
|
||||
void investigation_node_free(
|
||||
InvestigationNode *node
|
||||
);
|
||||
|
||||
const char *investigation_node_get_name(
|
||||
const InvestigationNode *node
|
||||
);
|
||||
|
||||
InvestigationNodeType investigation_node_get_type(
|
||||
const InvestigationNode *node
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comportement attendu
|
||||
|
||||
Exemple d'utilisation :
|
||||
|
||||
```c
|
||||
InvestigationNode *node = NULL;
|
||||
|
||||
node = investigation_node_new(
|
||||
"01_Preuves_Originales",
|
||||
INVESTIGATION_NODE_DIRECTORY
|
||||
);
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
/* Gestion de l'erreur */
|
||||
}
|
||||
|
||||
const char *name = investigation_node_get_name(node);
|
||||
InvestigationNodeType type = investigation_node_get_type(node);
|
||||
|
||||
investigation_node_free(node);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cas à gérer
|
||||
|
||||
- nom valide ;
|
||||
- nom vide ;
|
||||
- pointeur `NULL` ;
|
||||
- type dossier ;
|
||||
- type fichier ;
|
||||
- libération avec `NULL`.
|
||||
|
||||
---
|
||||
|
||||
## Contraintes techniques
|
||||
|
||||
- C17 ;
|
||||
- structure opaque ;
|
||||
- aucun état global ;
|
||||
- aucune dépendance GTK ;
|
||||
- documentation Doxygen ;
|
||||
- compilation sans warning ;
|
||||
- noms conformes à `DEVELOPMENT.md`.
|
||||
|
||||
---
|
||||
|
||||
## Critères d'acceptation
|
||||
|
||||
- [ ] Le projet compile sans warning.
|
||||
- [ ] La structure `InvestigationNode` est opaque.
|
||||
- [ ] Un nœud peut représenter un fichier.
|
||||
- [ ] Un nœud peut représenter un dossier.
|
||||
- [ ] Le nom est copié et possédé par le nœud.
|
||||
- [ ] Les getters retournent des données en lecture seule.
|
||||
- [ ] `investigation_node_free(NULL)` est accepté.
|
||||
- [ ] Aucun code GTK.
|
||||
- [ ] Aucun code SQLite.
|
||||
- [ ] Les fonctions publiques sont documentées avec Doxygen.
|
||||
|
||||
---
|
||||
|
||||
## Tests
|
||||
|
||||
- créer un nœud dossier ;
|
||||
- créer un nœud fichier ;
|
||||
- lire le nom ;
|
||||
- lire le type ;
|
||||
- tester un nom vide ;
|
||||
- tester un nom `NULL` ;
|
||||
- libérer un nœud valide ;
|
||||
- appeler `investigation_node_free(NULL)`.
|
||||
|
||||
---
|
||||
|
||||
## Commit attendu
|
||||
|
||||
```text
|
||||
feat(core): create investigation node
|
||||
```
|
||||
80
labfy-investigation/include/core/investigation_node.h
Normal file
80
labfy-investigation/include/core/investigation_node.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/******************************************************************************
|
||||
* @file investigation_node.h
|
||||
* @brief Interface publique d'un nœud de l'arborescence d'une enquête.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LABFY_INVESTIGATION_INVESTIGATION_NODE_H
|
||||
#define LABFY_INVESTIGATION_INVESTIGATION_NODE_H
|
||||
|
||||
/**
|
||||
* @brief Représentation opaque d'un nœud d'enquête.
|
||||
*
|
||||
* La structure réelle est définie dans investigation_node.c.
|
||||
* Les autres modules manipulent uniquement un pointeur vers
|
||||
* InvestigationNode.
|
||||
*/
|
||||
typedef struct InvestigationNode InvestigationNode;
|
||||
|
||||
/**
|
||||
* @brief Type d'un nœud de l'arborescence.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
INVESTIGATION_NODE_DIRECTORY,
|
||||
INVESTIGATION_NODE_FILE
|
||||
} InvestigationNodeType;
|
||||
|
||||
/**
|
||||
* @brief Crée un nouveau nœud d'enquête.
|
||||
*
|
||||
* Le nom fourni est copié. Le code appelant peut donc modifier ou libérer
|
||||
* sa chaîne après l'appel sans affecter le nœud.
|
||||
*
|
||||
* @param name Nom du fichier ou du dossier.
|
||||
* @param type Type du nœud.
|
||||
*
|
||||
* @return Un nouveau nœud, ou NULL si le nom est invalide ou si la création
|
||||
* échoue.
|
||||
*/
|
||||
InvestigationNode *investigation_node_new(
|
||||
const char *name,
|
||||
InvestigationNodeType type
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Libère les ressources associées à un nœud.
|
||||
*
|
||||
* Cette fonction accepte NULL.
|
||||
*
|
||||
* @param node Nœud à libérer.
|
||||
*/
|
||||
void investigation_node_free(
|
||||
InvestigationNode *node
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Retourne le nom du nœud.
|
||||
*
|
||||
* La chaîne retournée appartient au nœud et ne doit pas être modifiée
|
||||
* ni libérée par le code appelant.
|
||||
*
|
||||
* @param node Nœud à consulter.
|
||||
*
|
||||
* @return Le nom en lecture seule, ou NULL si node vaut NULL.
|
||||
*/
|
||||
const char *investigation_node_get_name(
|
||||
const InvestigationNode *node
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Retourne le type du nœud.
|
||||
*
|
||||
* @param node Nœud à consulter.
|
||||
*
|
||||
* @return Le type du nœud.
|
||||
*/
|
||||
InvestigationNodeType investigation_node_get_type(
|
||||
const InvestigationNode *node
|
||||
);
|
||||
|
||||
#endif
|
||||
Binary file not shown.
91
labfy-investigation/src/core/investigation_node.c
Normal file
91
labfy-investigation/src/core/investigation_node.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/******************************************************************************
|
||||
* @file investigation_node.c
|
||||
* @brief Implémentation d'un nœud d'enquête.
|
||||
******************************************************************************/
|
||||
|
||||
#include "core/investigation_node.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* @struct InvestigationNode
|
||||
* @brief Représentation interne d'un nœud.
|
||||
*/
|
||||
struct InvestigationNode
|
||||
{
|
||||
char *name;
|
||||
InvestigationNodeType type;
|
||||
};
|
||||
|
||||
InvestigationNode *investigation_node_new(
|
||||
const char *name,
|
||||
InvestigationNodeType type
|
||||
)
|
||||
{
|
||||
InvestigationNode *node = NULL;
|
||||
|
||||
if (name == NULL || name[0] == '\0')
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = g_new0(
|
||||
InvestigationNode,
|
||||
1
|
||||
);
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->name = g_strdup(name);
|
||||
|
||||
if (node->name == NULL)
|
||||
{
|
||||
investigation_node_free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->type = type;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void investigation_node_free(
|
||||
InvestigationNode *node
|
||||
)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_free(node->name);
|
||||
|
||||
g_free(node);
|
||||
}
|
||||
|
||||
const char *investigation_node_get_name(
|
||||
const InvestigationNode *node
|
||||
)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node->name;
|
||||
}
|
||||
|
||||
InvestigationNodeType investigation_node_get_type(
|
||||
const InvestigationNode *node
|
||||
)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return INVESTIGATION_NODE_FILE;
|
||||
}
|
||||
|
||||
return node->type;
|
||||
}
|
||||
BIN
labfy-investigation/tests/test_investigation_node
Executable file
BIN
labfy-investigation/tests/test_investigation_node
Executable file
Binary file not shown.
88
labfy-investigation/tests/test_investigation_node.c
Normal file
88
labfy-investigation/tests/test_investigation_node.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/******************************************************************************
|
||||
* @file test_investigation_node.c
|
||||
* @brief Tests du module InvestigationNode.
|
||||
******************************************************************************/
|
||||
|
||||
#include "core/investigation_node.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static void test_directory_node(void)
|
||||
{
|
||||
InvestigationNode *node = NULL;
|
||||
|
||||
node = investigation_node_new(
|
||||
"01_Preuves_Originales",
|
||||
INVESTIGATION_NODE_DIRECTORY
|
||||
);
|
||||
|
||||
assert(node != NULL);
|
||||
assert(strcmp(
|
||||
investigation_node_get_name(node),
|
||||
"01_Preuves_Originales"
|
||||
) == 0);
|
||||
assert(
|
||||
investigation_node_get_type(node) ==
|
||||
INVESTIGATION_NODE_DIRECTORY
|
||||
);
|
||||
|
||||
investigation_node_free(node);
|
||||
}
|
||||
|
||||
static void test_file_node(void)
|
||||
{
|
||||
InvestigationNode *node = NULL;
|
||||
|
||||
node = investigation_node_new(
|
||||
"Chronologie.md",
|
||||
INVESTIGATION_NODE_FILE
|
||||
);
|
||||
|
||||
assert(node != NULL);
|
||||
assert(strcmp(
|
||||
investigation_node_get_name(node),
|
||||
"Chronologie.md"
|
||||
) == 0);
|
||||
assert(
|
||||
investigation_node_get_type(node) ==
|
||||
INVESTIGATION_NODE_FILE
|
||||
);
|
||||
|
||||
investigation_node_free(node);
|
||||
}
|
||||
|
||||
static void test_invalid_names(void)
|
||||
{
|
||||
assert(
|
||||
investigation_node_new(
|
||||
NULL,
|
||||
INVESTIGATION_NODE_FILE
|
||||
) == NULL
|
||||
);
|
||||
|
||||
assert(
|
||||
investigation_node_new(
|
||||
"",
|
||||
INVESTIGATION_NODE_FILE
|
||||
) == NULL
|
||||
);
|
||||
}
|
||||
|
||||
static void test_null_free(void)
|
||||
{
|
||||
investigation_node_free(NULL);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_directory_node();
|
||||
test_file_node();
|
||||
test_invalid_names();
|
||||
test_null_free();
|
||||
|
||||
printf("InvestigationNode : tous les tests sont valides.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue