use super::*;
use crate::snippets::types::{SnippetAnnotation, SnippetMetadata, SourceOrigin};
use std::path::PathBuf;
fn snippet(language: crate::snippets::types::Language) -> Snippet {
Snippet {
id: None,
path: PathBuf::from("example.md"),
language,
title: None,
code: String::new(),
start_line: 1,
block_index: 0,
annotation: None,
metadata: SnippetMetadata::default(),
source_origin: SourceOrigin {
path: PathBuf::from("example.md"),
line: 1,
block_index: 0,
},
}
}
fn session_with_before(language: crate::snippets::types::Language, before: Vec<&str>) -> SessionSpec {
session_with_before_in(language, before, "/crate")
}
fn session_with_before_in(
language: crate::snippets::types::Language,
before: Vec<&str>,
working_directory: &str,
) -> SessionSpec {
SessionSpec {
language,
working_directory: PathBuf::from(working_directory),
manifest: None,
before: before.into_iter().map(str::to_string).collect(),
env: Default::default(),
include_paths: Vec::new(),
rust_features: Vec::new(),
rust_dependencies: Default::default(),
}
}
#[test]
fn a_language_with_no_configured_session_is_missing_a_build_dependency() {
use crate::snippets::types::Language;
let sessions = HashMap::new();
let snippets = vec![snippet(Language::Kotlin)];
let missing = missing_build_dependency(&snippets, &sessions, ValidationLevel::Compile);
assert_eq!(missing.get(&Language::Kotlin), Some(&1));
}
#[test]
fn a_session_with_an_empty_before_list_is_missing_a_build_dependency() {
use crate::snippets::types::Language;
let sessions = HashMap::from([("wasm".to_string(), session_with_before(Language::TypeScript, vec![]))]);
let snippets = vec![snippet(Language::TypeScript)];
let missing = missing_build_dependency(&snippets, &sessions, ValidationLevel::TypeCheck);
assert_eq!(missing.get(&Language::TypeScript), Some(&1));
}
#[test]
fn a_session_with_a_before_build_step_is_not_reported() {
use crate::snippets::types::Language;
let sessions = HashMap::from([(
"go".to_string(),
session_with_before(Language::Go, vec!["go build ./..."]),
)]);
let snippets = vec![snippet(Language::Go), snippet(Language::Go)];
let missing = missing_build_dependency(&snippets, &sessions, ValidationLevel::Compile);
assert!(missing.is_empty(), "a real before hook must clear the gap: {missing:?}");
}
#[test]
fn syntax_level_never_counts_as_a_missing_build_dependency() {
use crate::snippets::types::Language;
let sessions = HashMap::new();
let snippets = vec![snippet(Language::Kotlin)];
let missing = missing_build_dependency(&snippets, &sessions, ValidationLevel::Syntax);
assert!(
missing.is_empty(),
"syntax-level validation needs no artifact: {missing:?}"
);
}
#[test]
fn a_snippet_declared_at_syntax_level_is_not_reported_even_under_a_stronger_request() {
use crate::snippets::types::Language;
let sessions = HashMap::new();
let mut declared = snippet(Language::Kotlin);
declared.metadata.level = Some(ValidationLevel::Syntax);
let missing = missing_build_dependency(&[declared], &sessions, ValidationLevel::Run);
assert!(
missing.is_empty(),
"a declared syntax-only snippet needs no artifact: {missing:?}"
);
}
#[test]
fn a_skip_annotated_snippet_is_excluded() {
use crate::snippets::types::{Language, SnippetAnnotationKind};
let sessions = HashMap::new();
let mut skipped = snippet(Language::Kotlin);
skipped.annotation = Some(SnippetAnnotation {
kind: SnippetAnnotationKind::Skip,
reason: Some("documented elsewhere".to_string()),
});
let missing = missing_build_dependency(&[skipped], &sessions, ValidationLevel::Compile);
assert!(
missing.is_empty(),
"a skipped snippet never runs, so it is not a build gap: {missing:?}"
);
}
#[test]
fn an_ambiguous_claim_is_reported_as_missing_a_build_dependency() {
use crate::snippets::types::Language;
let sessions = HashMap::from([
(
"typescript".to_string(),
session_with_before_in(Language::TypeScript, vec!["pnpm build"], "/packages/typescript"),
),
(
"wasm".to_string(),
session_with_before_in(Language::TypeScript, vec!["wasm-pack build"], "/packages/wasm"),
),
]);
let snippets = vec![snippet(Language::TypeScript)];
let missing = missing_build_dependency(&snippets, &sessions, ValidationLevel::Compile);
assert_eq!(missing.get(&Language::TypeScript), Some(&1));
}
#[test]
fn counts_are_kept_separate_per_language() {
use crate::snippets::types::Language;
let sessions = HashMap::new();
let snippets = vec![
snippet(Language::Kotlin),
snippet(Language::Kotlin),
snippet(Language::TypeScript),
];
let missing = missing_build_dependency(&snippets, &sessions, ValidationLevel::Compile);
assert_eq!(missing.get(&Language::Kotlin), Some(&2));
assert_eq!(missing.get(&Language::TypeScript), Some(&1));
}