0.0.1-alpha.5.fix.1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: CHANGELOG.md -->
|
<!-- file: CHANGELOG.md -->
|
||||||
<!-- version: 7 -->
|
<!-- version: 8 -->
|
||||||
|
|
||||||
# Changelog SaseDev Knowledge
|
# Changelog SaseDev Knowledge
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ Ce fichier décrit les changements utiles des releases publiées. Les détails d
|
|||||||
- instancie le workspace Rust/Cargo strict avec une première crate de domaine et une politique explicite de `Cargo.lock` versionné ;
|
- instancie le workspace Rust/Cargo strict avec une première crate de domaine et une politique explicite de `Cargo.lock` versionné ;
|
||||||
- introduit les premiers contrats provider-neutral de source, Git et synchronisation sans dépendance à une forge ni à PostgreSQL ;
|
- introduit les premiers contrats provider-neutral de source, Git et synchronisation sans dépendance à une forge ni à PostgreSQL ;
|
||||||
- active les audits Rust PGR de structure et de façade au moment où des API publiques réelles apparaissent ;
|
- active les audits Rust PGR de structure et de façade au moment où des API publiques réelles apparaissent ;
|
||||||
|
- sélectionne localement `unit_tests/` hors de `src/` pour tous les tests unitaires Rust, avec `tests/` réservé aux tests d'intégration Cargo ;
|
||||||
- fixe le frontend Web PGR comme laboratoire de validation des templates statiques et des assets avant adaptation du markup runtime en Maud ;
|
- fixe le frontend Web PGR comme laboratoire de validation des templates statiques et des assets avant adaptation du markup runtime en Maud ;
|
||||||
- matérialise ce laboratoire sous `Web/knowledge-template-lab/` avec npm, TypeScript strict, Vite, Sass, Bootstrap et manifest Vite ;
|
- matérialise ce laboratoire sous `Web/knowledge-template-lab/` avec npm, TypeScript strict, Vite, Sass, Bootstrap et manifest Vite ;
|
||||||
- retient l’intégration production Actix/Maud via le manifest Vite comme contrat d’asset mapping à réimplémenter proprement, sans copier mécaniquement le corpus historique ;
|
- retient l’intégration production Actix/Maud via le manifest Vite comme contrat d’asset mapping à réimplémenter proprement, sans copier mécaniquement le corpus historique ;
|
||||||
|
|||||||
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -475,46 +475,46 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-domain-lib"
|
name = "knowledge-domain-lib"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-git-api"
|
name = "knowledge-git-api"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"knowledge-domain-lib",
|
"knowledge-domain-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-howtos-server"
|
name = "knowledge-howtos-server"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"knowledge-web-lib",
|
"knowledge-web-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-pgr-server"
|
name = "knowledge-pgr-server"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"knowledge-web-lib",
|
"knowledge-web-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-snippets-server"
|
name = "knowledge-snippets-server"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"knowledge-web-lib",
|
"knowledge-web-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-sync-api"
|
name = "knowledge-sync-api"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"knowledge-domain-lib",
|
"knowledge-domain-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "knowledge-web-lib"
|
name = "knowledge-web-lib"
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-files",
|
"actix-files",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 9
|
# version: 10
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
@@ -14,7 +14,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.0.1-alpha.5"
|
version = "0.0.1-alpha.5.fix.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
publish = false
|
publish = false
|
||||||
repository = "https://git.sasedev.com/Sasedev/sasedev-knowledge"
|
repository = "https://git.sasedev.com/Sasedev/sasedev-knowledge"
|
||||||
|
|||||||
23
RULES.md
23
RULES.md
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: RULES.md -->
|
<!-- file: RULES.md -->
|
||||||
<!-- version: 7 -->
|
<!-- version: 8 -->
|
||||||
|
|
||||||
# Règles SaseDev Knowledge
|
# Règles SaseDev Knowledge
|
||||||
|
|
||||||
@@ -183,6 +183,27 @@ Les trois launchers MUST recevoir leur socket de bind par configuration (`KNOWLE
|
|||||||
|
|
||||||
## Rust et crates
|
## Rust et crates
|
||||||
|
|
||||||
|
Knowledge sélectionne localement la convention `unit_tests/` séparée que PGR `0.1.1` autorise sans l'imposer globalement.
|
||||||
|
|
||||||
|
Pour toutes les crates Rust de ce workspace :
|
||||||
|
|
||||||
|
- les tests d'intégration Cargo MUST résider sous `tests/` et consommer l'API publique de la crate ;
|
||||||
|
- les tests unitaires MUST résider sous `unit_tests/` à la racine de la crate, en miroir logique de `src/` ;
|
||||||
|
- `src/` MUST NOT contenir de fichier d'implémentation de tests unitaires ni d'attribut `#[test]` ;
|
||||||
|
- un module source rattache son fichier de tests avec `#[cfg(test)]` et `#[path = "../unit_tests/<fichier>.rs"]` ou le chemin miroir équivalent ;
|
||||||
|
- les tests unitaires d'un item partagé continuent d'utiliser son identité crate-root conformément à PGR ;
|
||||||
|
- `tests/` MUST NOT être utilisé pour contourner la visibilité interne ou héberger des tests unitaires qui dépendent d'éléments privés.
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/bite.rs"]
|
||||||
|
mod tests;
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette convention locale est plus stricte que le `MAY` générique de PGR, mais reste conforme à celui-ci. Si PGR doit l'imposer à tous les futurs workspaces, cette évolution appartient à une version ultérieure du référentiel PGR et non à Knowledge.
|
||||||
|
|
||||||
Le préfixe de crate retenu est `knowledge-`.
|
Le préfixe de crate retenu est `knowledge-`.
|
||||||
|
|
||||||
Les responsabilités candidates sont documentées dans l'architecture. Une crate n'est matérialisée que lorsqu'elle possède une responsabilité réelle. Le suffixe `-api` n'est utilisé que pour une frontière passive dont des implémentations distinctes/remplaçables sont réellement prévues.
|
Les responsabilités candidates sont documentées dans l'architecture. Une crate n'est matérialisée que lorsqu'elle possède une responsabilité réelle. Le suffixe `-api` n'est utilisé que pour une frontière passive dont des implémentations distinctes/remplaçables sont réellement prévues.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-domain-lib/src/lib.rs
|
// file: crates/knowledge-domain-lib/src/lib.rs
|
||||||
// version: 2
|
// version: 3
|
||||||
|
|
||||||
//! Shared domain contracts for SaseDev Knowledge.
|
//! Shared domain contracts for SaseDev Knowledge.
|
||||||
//!
|
//!
|
||||||
@@ -11,6 +11,3 @@ mod source;
|
|||||||
|
|
||||||
pub use crate::content_family::ContentFamily;
|
pub use crate::content_family::ContentFamily;
|
||||||
pub use crate::source::{ContentSource, SourceId, SourceIdError};
|
pub use crate::source::{ContentSource, SourceId, SourceIdError};
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod unit_tests;
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-domain-lib/src/source.rs
|
// file: crates/knowledge-domain-lib/src/source.rs
|
||||||
// version: 2
|
// version: 3
|
||||||
|
|
||||||
//! Source identities independent of repository and forge providers.
|
//! Source identities independent of repository and forge providers.
|
||||||
|
|
||||||
@@ -66,3 +66,7 @@ impl crate::ContentSource {
|
|||||||
return self.family;
|
return self.family;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/source.rs"]
|
||||||
|
mod tests;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-domain-lib/src/unit_tests.rs
|
// file: crates/knowledge-domain-lib/unit_tests/source.rs
|
||||||
// version: 2
|
// version: 1
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn source_id_rejects_empty_values() {
|
fn source_id_rejects_empty_values() {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-git-api/src/lib.rs
|
// file: crates/knowledge-git-api/src/lib.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
//! Provider-neutral contracts for Git-backed Knowledge sources.
|
//! Provider-neutral contracts for Git-backed Knowledge sources.
|
||||||
//!
|
//!
|
||||||
@@ -54,4 +54,5 @@ pub trait GitRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod unit_tests;
|
#[path = "../unit_tests/lib.rs"]
|
||||||
|
mod tests;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// file: crates/knowledge-git-api/src/unit_tests.rs
|
// file: crates/knowledge-git-api/unit_tests/lib.rs
|
||||||
// version: 1
|
// version: 1
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-sync-api/src/lib.rs
|
// file: crates/knowledge-sync-api/src/lib.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
//! Contracts for provider-neutral repository synchronization signals.
|
//! Contracts for provider-neutral repository synchronization signals.
|
||||||
//!
|
//!
|
||||||
@@ -54,4 +54,5 @@ pub trait RepositoryEventSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod unit_tests;
|
#[path = "../unit_tests/lib.rs"]
|
||||||
|
mod tests;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// file: crates/knowledge-sync-api/src/unit_tests.rs
|
// file: crates/knowledge-sync-api/unit_tests/lib.rs
|
||||||
// version: 1
|
// version: 1
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-web-lib/src/assets.rs
|
// file: crates/knowledge-web-lib/src/assets.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
//! Vite development and production asset resolution.
|
//! Vite development and production asset resolution.
|
||||||
|
|
||||||
@@ -193,3 +193,7 @@ fn local_static_mount_path(base: &str) -> Option<String> {
|
|||||||
}
|
}
|
||||||
return Some(format!("{}/assets", normalized.trim_end_matches('/')));
|
return Some(format!("{}/assets", normalized.trim_end_matches('/')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/assets.rs"]
|
||||||
|
mod tests;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-web-lib/src/lib.rs
|
// file: crates/knowledge-web-lib/src/lib.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
//! Shared Actix Web and Maud composition for the three Knowledge server launchers.
|
//! Shared Actix Web and Maud composition for the three Knowledge server launchers.
|
||||||
//!
|
//!
|
||||||
@@ -22,6 +22,3 @@ pub(crate) use self::assets::ViteAssets;
|
|||||||
pub(crate) use self::assets::load_assets_from_environment;
|
pub(crate) use self::assets::load_assets_from_environment;
|
||||||
/// Internal Maud renderer for the public foundation page.
|
/// Internal Maud renderer for the public foundation page.
|
||||||
pub(crate) use self::page::render_index_page;
|
pub(crate) use self::page::render_index_page;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod unit_tests;
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/knowledge-web-lib/src/page.rs
|
// file: crates/knowledge-web-lib/src/page.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
//! Maud rendering adapted from the static template-lab contract.
|
//! Maud rendering adapted from the static template-lab contract.
|
||||||
|
|
||||||
@@ -50,3 +50,7 @@ fn family_slug(family: knowledge_domain_lib::ContentFamily) -> &'static str {
|
|||||||
knowledge_domain_lib::ContentFamily::ProjectLocal => return "project-local",
|
knowledge_domain_lib::ContentFamily::ProjectLocal => return "project-local",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/page.rs"]
|
||||||
|
mod tests;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// file: crates/knowledge-web-lib/src/unit_tests.rs
|
// file: crates/knowledge-web-lib/unit_tests/assets.rs
|
||||||
// version: 1
|
// version: 1
|
||||||
|
|
||||||
//! Unit tests for shared Web composition primitives.
|
//! Unit tests for Vite asset resolution.
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn development_assets_include_vite_client_before_main_entry() {
|
fn development_assets_include_vite_client_before_main_entry() {
|
||||||
@@ -50,23 +50,3 @@ fn manifest_requires_the_stable_main_entry() {
|
|||||||
let result = crate::ViteAssets::from_manifest_text(manifest, "/", std::path::PathBuf::from("/tmp/knowledge-assets"));
|
let result = crate::ViteAssets::from_manifest_text(manifest, "/", std::path::PathBuf::from("/tmp/knowledge-assets"));
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maud_page_uses_resolved_assets_and_site_identity() {
|
|
||||||
let assets = match crate::ViteAssets::from_manifest_text(
|
|
||||||
r#"{"src/main.ts": {"file": "assets/main.js", "css": ["assets/main.css"], "isEntry": true}}"#,
|
|
||||||
"/",
|
|
||||||
std::path::PathBuf::from("/tmp/knowledge-assets"),
|
|
||||||
) {
|
|
||||||
Ok(value) => value,
|
|
||||||
Err(error) => {
|
|
||||||
assert!(error.is_empty(), "unexpected manifest error: {error}");
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let rendered = crate::render_index_page(crate::ServerSite::Pgr, &assets).into_string();
|
|
||||||
assert!(rendered.contains("SaseDev Knowledge — PGR"));
|
|
||||||
assert!(rendered.contains("/assets/main.js"));
|
|
||||||
assert!(rendered.contains("/assets/main.css"));
|
|
||||||
assert!(rendered.contains("data-content-family=\"pgr\""));
|
|
||||||
}
|
|
||||||
24
crates/knowledge-web-lib/unit_tests/page.rs
Normal file
24
crates/knowledge-web-lib/unit_tests/page.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// file: crates/knowledge-web-lib/unit_tests/page.rs
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
//! Unit tests for Maud page rendering.
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn maud_page_uses_resolved_assets_and_site_identity() {
|
||||||
|
let assets = match crate::ViteAssets::from_manifest_text(
|
||||||
|
r#"{"src/main.ts": {"file": "assets/main.js", "css": ["assets/main.css"], "isEntry": true}}"#,
|
||||||
|
"/",
|
||||||
|
std::path::PathBuf::from("/tmp/knowledge-assets"),
|
||||||
|
) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(error) => {
|
||||||
|
assert!(error.is_empty(), "unexpected manifest error: {error}");
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let rendered = crate::render_index_page(crate::ServerSite::Pgr, &assets).into_string();
|
||||||
|
assert!(rendered.contains("SaseDev Knowledge — PGR"));
|
||||||
|
assert!(rendered.contains("/assets/main.js"));
|
||||||
|
assert!(rendered.contains("/assets/main.css"));
|
||||||
|
assert!(rendered.contains("data-content-family=\"pgr\""));
|
||||||
|
}
|
||||||
130
deltas/0.0.1/alpha.5.fix.1.md
Normal file
130
deltas/0.0.1/alpha.5.fix.1.md
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
<!-- file: deltas/0.0.1/alpha.5.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.1-alpha.5.fix.1 — layout séparé des tests unitaires Rust
|
||||||
|
|
||||||
|
## Base requise
|
||||||
|
|
||||||
|
État `0.0.1-alpha.5` committé et poussé après application du history :
|
||||||
|
|
||||||
|
```text
|
||||||
|
history/0.0.1/alpha.5.md = FAIL
|
||||||
|
```
|
||||||
|
|
||||||
|
La version devient :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.1-alpha.5.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cause
|
||||||
|
|
||||||
|
La gate technique d'`alpha.5` passe, y compris les tests de `knowledge-web-lib` et les smokes HTTP.
|
||||||
|
|
||||||
|
La revue de gouvernance opérateur relève cependant que les tests unitaires restent sous `src/unit_tests.rs`.
|
||||||
|
|
||||||
|
PGR `0.1.1` autorise une arborescence `unit_tests/` séparée avec la modalité `MAY`. Knowledge sélectionne désormais explicitement cette convention comme règle locale `MUST`.
|
||||||
|
|
||||||
|
Le défaut concerne quatre crates et doit être corrigé de manière cohérente.
|
||||||
|
|
||||||
|
## Arborescence cible
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/<crate>/
|
||||||
|
src/
|
||||||
|
unit_tests/
|
||||||
|
tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
- `unit_tests/` : tests unitaires attachés aux modules source par `#[path = "..."]` ;
|
||||||
|
- `tests/` : tests d'intégration Cargo qui consomment l'API publique.
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/source.rs"]
|
||||||
|
mod tests;
|
||||||
|
```
|
||||||
|
|
||||||
|
## ADD
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/knowledge-domain-lib/unit_tests/source.rs
|
||||||
|
crates/knowledge-git-api/unit_tests/lib.rs
|
||||||
|
crates/knowledge-sync-api/unit_tests/lib.rs
|
||||||
|
crates/knowledge-web-lib/unit_tests/assets.rs
|
||||||
|
crates/knowledge-web-lib/unit_tests/page.rs
|
||||||
|
scripts/audit_rust_test_layout.py
|
||||||
|
manifests/0.0.1/alpha.5.fix.1.delete.txt
|
||||||
|
deltas/0.0.1/alpha.5.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## REPLACE
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
Cargo.toml
|
||||||
|
CHANGELOG.md
|
||||||
|
RULES.md
|
||||||
|
crates/knowledge-domain-lib/src/lib.rs
|
||||||
|
crates/knowledge-domain-lib/src/source.rs
|
||||||
|
crates/knowledge-git-api/src/lib.rs
|
||||||
|
crates/knowledge-sync-api/src/lib.rs
|
||||||
|
crates/knowledge-web-lib/src/lib.rs
|
||||||
|
crates/knowledge-web-lib/src/assets.rs
|
||||||
|
crates/knowledge-web-lib/src/page.rs
|
||||||
|
docs/plans/001-V0_0_1_FOUNDATION_PLAN.md
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## DELETE
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/knowledge-domain-lib/src/unit_tests.rs
|
||||||
|
crates/knowledge-git-api/src/unit_tests.rs
|
||||||
|
crates/knowledge-sync-api/src/unit_tests.rs
|
||||||
|
crates/knowledge-web-lib/src/unit_tests.rs
|
||||||
|
```
|
||||||
|
|
||||||
|
Les suppressions sont possédées par :
|
||||||
|
|
||||||
|
```text
|
||||||
|
manifests/0.0.1/alpha.5.fix.1.delete.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Audit ajouté
|
||||||
|
|
||||||
|
`audit_rust_test_layout.py` vérifie :
|
||||||
|
|
||||||
|
- absence de `#[test]` sous `src/` ;
|
||||||
|
- absence de fichiers `src/tests.rs` et `src/unit_tests.rs` ;
|
||||||
|
- absence de `mod unit_tests;` classique ;
|
||||||
|
- rattachement effectif de chaque fichier sous `unit_tests/` par un `#[path = "..."]`.
|
||||||
|
|
||||||
|
L'audit ne traite pas `tests/` comme tests internes.
|
||||||
|
|
||||||
|
## Scope fonctionnel
|
||||||
|
|
||||||
|
Aucun comportement métier ou HTTP n'est modifié.
|
||||||
|
|
||||||
|
Les routes, assets, rendu Maud, manifest Vite, binds et trois launchers restent identiques à `alpha.5`.
|
||||||
|
|
||||||
|
## Application des suppressions
|
||||||
|
|
||||||
|
Après extraction du delta, appliquer exactement le manifest :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
while IFS= read -r path; do
|
||||||
|
test -n "$path" || continue
|
||||||
|
rm -f -- "$path"
|
||||||
|
done < manifests/0.0.1/alpha.5.fix.1.delete.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Ne pas supprimer d'autre chemin.
|
||||||
|
|
||||||
|
## Validation attendue
|
||||||
|
|
||||||
|
La gate doit prouver l'arborescence, les rattachements, les audits Rust, Cargo/Clippy/tests, la baseline Web et les trois smokes HTTP.
|
||||||
|
|
||||||
|
Ne pas committe `alpha.5.fix.1` avant production de son history à partir des résultats opérateur.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/001-V0_0_1_FOUNDATION_PLAN.md -->
|
<!-- file: docs/plans/001-V0_0_1_FOUNDATION_PLAN.md -->
|
||||||
<!-- version: 11 -->
|
<!-- version: 12 -->
|
||||||
|
|
||||||
# Plan 0.0.1 — fondation SaseDev Knowledge
|
# Plan 0.0.1 — fondation SaseDev Knowledge
|
||||||
|
|
||||||
@@ -203,6 +203,18 @@ La gate doit couvrir les tests `knowledge-web-lib`, la compilation/Clippy des qu
|
|||||||
|
|
||||||
La tranche ne doit pas introduire admin complète, auth complète, persistance métier complète, logging transverse artificiel ni forge obligatoire.
|
La tranche ne doit pas introduire admin complète, auth complète, persistance métier complète, logging transverse artificiel ni forge obligatoire.
|
||||||
|
|
||||||
|
La gate technique d'`alpha.5` est verte : structure, Web, Cargo, Clippy, tests et smokes HTTP passent. La tranche reste néanmoins **FAIL** après revue opérateur de gouvernance : les tests unitaires sont encore implémentés sous `src/unit_tests.rs`, alors que Knowledge sélectionne désormais la convention PGR optionnelle `unit_tests/` séparée et miroir de `src/`.
|
||||||
|
|
||||||
|
Le défaut existait déjà dans les trois crates antérieures et est également introduit par `knowledge-web-lib`; il doit donc être corrigé globalement et non seulement dans la nouvelle crate.
|
||||||
|
|
||||||
|
`alpha.5.fix.1` :
|
||||||
|
|
||||||
|
- formalise cette convention locale comme `MUST` dans `RULES.md` ;
|
||||||
|
- déplace les tests unitaires des quatre crates concernées sous `unit_tests/` ;
|
||||||
|
- rattache les tests avec `#[cfg(test)]` + `#[path = "..."]` ;
|
||||||
|
- conserve `tests/` pour les tests d'intégration Cargo uniquement ;
|
||||||
|
- ajoute un audit monotâche empêchant le retour de `#[test]` ou de fichiers `unit_tests.rs` sous `src/`.
|
||||||
|
|
||||||
### beta.1 — réconciliation de fondation
|
### beta.1 — réconciliation de fondation
|
||||||
|
|
||||||
Rejouer les gates pertinentes, réconcilier docs/architecture avec ce qui existe réellement, traiter les décisions devenues nécessaires et effectuer la revue d'horizon.
|
Rejouer les gates pertinentes, réconcilier docs/architecture avec ce qui existe réellement, traiter les décisions devenues nécessaires et effectuer la revue d'horizon.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
|
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
|
||||||
<!-- version: 11 -->
|
<!-- version: 12 -->
|
||||||
|
|
||||||
# Matrice de validation Knowledge
|
# Matrice de validation Knowledge
|
||||||
|
|
||||||
@@ -316,3 +316,50 @@ La composition serveur doit prouver :
|
|||||||
- audits Rust PGR, `cargo check`, Clippy strict et tests ciblés `PASS` ;
|
- audits Rust PGR, `cargo check`, Clippy strict et tests ciblés `PASS` ;
|
||||||
- smoke HTTP production `PASS` pour les trois launchers avec ports de test injectés par environnement ;
|
- smoke HTTP production `PASS` pour les trois launchers avec ports de test injectés par environnement ;
|
||||||
- `Cargo.lock` mis à jour/versionné et staging propre.
|
- `Cargo.lock` mis à jour/versionné et staging propre.
|
||||||
|
|
||||||
|
## Convention locale des tests Rust
|
||||||
|
|
||||||
|
Knowledge sélectionne la convention PGR optionnelle suivante comme règle locale obligatoire :
|
||||||
|
|
||||||
|
```text
|
||||||
|
crate/
|
||||||
|
src/
|
||||||
|
unit_tests/
|
||||||
|
tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
`unit_tests/` contient les tests unitaires attachés aux modules source par `#[path = "..."]`.
|
||||||
|
|
||||||
|
`tests/` contient exclusivement les tests d'intégration Cargo qui consomment l'API publique.
|
||||||
|
|
||||||
|
La gate Rust ajoute :
|
||||||
|
|
||||||
|
```text
|
||||||
|
python3 -B scripts/audit_rust_test_layout.py crates
|
||||||
|
```
|
||||||
|
|
||||||
|
Cet audit doit refuser notamment :
|
||||||
|
|
||||||
|
- un attribut `#[test]` dans `src/` ;
|
||||||
|
- un fichier `src/unit_tests.rs` ou `src/tests.rs` ;
|
||||||
|
- un `mod unit_tests;` classique sous `src/` ;
|
||||||
|
- un fichier sous `unit_tests/` qui n'est référencé par aucun `#[path = "..."]` d'un source de la crate.
|
||||||
|
|
||||||
|
## Gate de `0.0.1-alpha.5.fix.1`
|
||||||
|
|
||||||
|
Le fix de layout des tests doit prouver :
|
||||||
|
|
||||||
|
- `VERSION = 0.0.1-alpha.5.fix.1` et version workspace identique ;
|
||||||
|
- history `alpha.5` `FAIL` committé avant application ;
|
||||||
|
- suppression exacte des quatre anciens `src/unit_tests.rs` via le manifest de suppression ;
|
||||||
|
- tests unitaires sous `unit_tests/` hors de `src/` pour `knowledge-domain-lib`, `knowledge-git-api`, `knowledge-sync-api` et `knowledge-web-lib` ;
|
||||||
|
- rattachements `#[cfg(test)]` + `#[path = "..."]` depuis les modules source propriétaires ;
|
||||||
|
- aucun `#[test]` sous `crates/*/src/` ;
|
||||||
|
- `tests/` réservé aux futurs tests d'intégration Cargo ;
|
||||||
|
- `audit_rust_test_layout.py` `PASS` ;
|
||||||
|
- audits Rust PGR existants toujours `PASS`, y compris export completeness qui suit les modules `#[path]` ;
|
||||||
|
- `cargo check`, Clippy strict et `cargo test --workspace --all-targets --all-features` `PASS` ;
|
||||||
|
- baseline Web `npm ci`, typecheck et build `PASS` ;
|
||||||
|
- smoke HTTP production des trois serveurs `PASS` ;
|
||||||
|
- aucune modification fonctionnelle Actix/Maud/Vite au-delà du rattachement des tests ;
|
||||||
|
- `git diff --cached --check` propre.
|
||||||
|
|||||||
63
history/0.0.1/alpha.5.fix.1.md
Normal file
63
history/0.0.1/alpha.5.fix.1.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<!-- file: history/0.0.1/alpha.5.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# History 0.0.1-alpha.5.fix.1 — layout séparé des tests unitaires Rust
|
||||||
|
|
||||||
|
## Statut
|
||||||
|
|
||||||
|
FAIL
|
||||||
|
|
||||||
|
La gate opérateur de `0.0.1-alpha.5.fix.1` exécutée le `2026-09-28` confirme la migration fonctionnelle des tests unitaires hors de `src/`, mais le premier contrôle d'hygiène Git échoue sur deux lignes vides terminales.
|
||||||
|
|
||||||
|
## Baseline opérateur
|
||||||
|
|
||||||
|
`alpha.5` `FAIL` a été historisé, committé et poussé avant application du fix :
|
||||||
|
|
||||||
|
```text
|
||||||
|
history/0.0.1/alpha.5.md = FAIL
|
||||||
|
commit c17b706
|
||||||
|
message 0.0.1-alpha.5
|
||||||
|
branch master
|
||||||
|
push origin/master PASS
|
||||||
|
status clean après push
|
||||||
|
```
|
||||||
|
|
||||||
|
Le push observé a avancé `origin/master` de `8f6f072` à `c17b706`.
|
||||||
|
|
||||||
|
## Layout des tests
|
||||||
|
|
||||||
|
Le manifest de suppression contient exactement les quatre anciens `src/unit_tests.rs`, qui sont supprimés avant la gate. La preuve structurelle passe :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Knowledge 0.0.1-alpha.5.fix.1 test layout: clean
|
||||||
|
Rust test-layout audit: clean (7 crate(s))
|
||||||
|
```
|
||||||
|
|
||||||
|
Les cinq fichiers unitaires résident désormais sous `unit_tests/` et leurs tests apparaissent sous les modules propriétaires (`source::tests`, `assets::tests`, `page::tests`).
|
||||||
|
|
||||||
|
## Défaut bloquant initial
|
||||||
|
|
||||||
|
Le premier `git diff --check` échoue avec :
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/knowledge-domain-lib/src/lib.rs:14: new blank line at EOF.
|
||||||
|
crates/knowledge-web-lib/src/lib.rs:25: new blank line at EOF.
|
||||||
|
```
|
||||||
|
|
||||||
|
La tranche reste donc `FAIL`.
|
||||||
|
|
||||||
|
## Normalisation et preuves suivantes
|
||||||
|
|
||||||
|
`cargo fmt --all` puis `cargo fmt --all -- --check` passent et normalisent les fins de fichiers. Les audits Rust passent sur 18 fichiers et 7 crates/packages. `cargo check`, Clippy strict et tous les tests workspace passent : 3 + 1 + 1 + 4 tests, launchers à 0 test.
|
||||||
|
|
||||||
|
La baseline Web passe également : `npm ci`, typecheck et build Vite. Les warnings Sass Bootstrap et `@parcel/watcher@2.6.0` restent des observations non bloquantes déjà connues.
|
||||||
|
|
||||||
|
Le transcript du fix ne contient pas le rejeu demandé des trois smokes HTTP. La preuve historique d'`alpha.5` ne remplace pas cette preuve de fix.
|
||||||
|
|
||||||
|
Le `git diff --cached --check` final est propre et le staging reflète les renommages/suppressions gouvernés ainsi que les cinq fichiers `unit_tests/`.
|
||||||
|
|
||||||
|
## Décision
|
||||||
|
|
||||||
|
`0.0.1-alpha.5.fix.1` est `FAIL`.
|
||||||
|
|
||||||
|
La transition autorisée est `0.0.1-alpha.5.fix.2`, depuis le snapshot FAIL déjà normalisé, avec gate sans formatage mutateur préalable et trois smokes HTTP explicitement rejoués.
|
||||||
4
manifests/0.0.1/alpha.5.fix.1.delete.txt
Normal file
4
manifests/0.0.1/alpha.5.fix.1.delete.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
crates/knowledge-domain-lib/src/unit_tests.rs
|
||||||
|
crates/knowledge-git-api/src/unit_tests.rs
|
||||||
|
crates/knowledge-sync-api/src/unit_tests.rs
|
||||||
|
crates/knowledge-web-lib/src/unit_tests.rs
|
||||||
82
scripts/audit_rust_test_layout.py
Normal file
82
scripts/audit_rust_test_layout.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# file: scripts/audit_rust_test_layout.py
|
||||||
|
# version: 1
|
||||||
|
|
||||||
|
"""Audit the Knowledge Rust unit/integration test layout."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
_TEST_ATTRIBUTE = re.compile(r"(?m)^\s*#\s*\[\s*test\s*\]")
|
||||||
|
_PATH_ATTRIBUTE = re.compile(r'#\s*\[\s*path\s*=\s*"([^"]+)"\s*\]')
|
||||||
|
_FORBIDDEN_MODULE = re.compile(r"(?m)^\s*mod\s+unit_tests\s*;")
|
||||||
|
|
||||||
|
|
||||||
|
def audit_crate(crate_root: pathlib.Path) -> list[str]:
|
||||||
|
"""Return layout violations for one crate."""
|
||||||
|
errors: list[str] = []
|
||||||
|
src_root = crate_root / "src"
|
||||||
|
referenced_unit_tests: set[pathlib.Path] = set()
|
||||||
|
|
||||||
|
if src_root.is_dir():
|
||||||
|
for source in sorted(src_root.rglob("*.rs")):
|
||||||
|
text = source.read_text(encoding="utf-8")
|
||||||
|
relative = source.relative_to(crate_root)
|
||||||
|
|
||||||
|
if _TEST_ATTRIBUTE.search(text):
|
||||||
|
errors.append(f"{crate_root.name}/{relative}: #[test] must live under unit_tests/")
|
||||||
|
|
||||||
|
if source.name in {"tests.rs", "unit_tests.rs"}:
|
||||||
|
errors.append(f"{crate_root.name}/{relative}: test implementation file must not live under src/")
|
||||||
|
|
||||||
|
if _FORBIDDEN_MODULE.search(text):
|
||||||
|
errors.append(f"{crate_root.name}/{relative}: use #[path = \"../unit_tests/...\"] instead of mod unit_tests;")
|
||||||
|
|
||||||
|
for match in _PATH_ATTRIBUTE.finditer(text):
|
||||||
|
candidate = (source.parent / match.group(1)).resolve()
|
||||||
|
try:
|
||||||
|
candidate.relative_to((crate_root / "unit_tests").resolve())
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
referenced_unit_tests.add(candidate)
|
||||||
|
|
||||||
|
unit_root = crate_root / "unit_tests"
|
||||||
|
if unit_root.is_dir():
|
||||||
|
for test_file in sorted(unit_root.rglob("*.rs")):
|
||||||
|
resolved = test_file.resolve()
|
||||||
|
if resolved not in referenced_unit_tests:
|
||||||
|
relative = test_file.relative_to(crate_root)
|
||||||
|
errors.append(f"{crate_root.name}/{relative}: unit test file is not attached by any #[path] module")
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
"""Run the audit."""
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("root", nargs="?", default="crates")
|
||||||
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
|
root = pathlib.Path(arguments.root)
|
||||||
|
errors: list[str] = []
|
||||||
|
crate_count = 0
|
||||||
|
|
||||||
|
for manifest in sorted(root.glob("*/Cargo.toml")):
|
||||||
|
crate_count += 1
|
||||||
|
errors.extend(audit_crate(manifest.parent))
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
for error in errors:
|
||||||
|
print(error, file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(f"Rust test-layout audit: clean ({crate_count} crate(s))")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user