use std::collections::{HashMap, HashSet};
use crate::config::E2eConfig;
use crate::fixture::Fixture;
pub(super) fn resolve_function_name(e2e_config: &E2eConfig) -> String {
resolve_function_name_for_call(&e2e_config.call)
}
pub(super) fn resolve_function_name_for_call(call_config: &crate::config::CallConfig) -> String {
call_config
.overrides
.get("python")
.and_then(|o| o.function.clone())
.unwrap_or_else(|| call_config.function.clone())
}
pub(super) fn resolve_module(e2e_config: &E2eConfig) -> String {
e2e_config
.call
.overrides
.get("python")
.and_then(|o| o.module.clone())
.unwrap_or_else(|| e2e_config.call.module.replace('-', "_"))
}
pub(super) fn resolve_options_type(e2e_config: &E2eConfig) -> Option<String> {
e2e_config
.call
.overrides
.get("python")
.and_then(|o| o.options_type.clone())
}
pub(super) fn resolve_client_factory(e2e_config: &E2eConfig) -> Option<String> {
e2e_config
.call
.overrides
.get("python")
.and_then(|o| o.client_factory.clone())
}
pub(super) fn resolve_options_via(e2e_config: &E2eConfig) -> &str {
e2e_config
.call
.overrides
.get("python")
.and_then(|o| o.options_via.as_deref())
.unwrap_or("kwargs")
}
pub(super) fn resolve_enum_fields(e2e_config: &E2eConfig) -> &HashMap<String, String> {
static EMPTY: std::sync::LazyLock<HashMap<String, String>> = std::sync::LazyLock::new(HashMap::new);
e2e_config
.call
.overrides
.get("python")
.map(|o| &o.enum_fields)
.unwrap_or(&EMPTY)
}
pub(super) fn resolve_assert_enum_fields(call_config: &crate::config::CallConfig) -> &HashMap<String, String> {
static EMPTY: std::sync::LazyLock<HashMap<String, String>> = std::sync::LazyLock::new(HashMap::new);
call_config
.overrides
.get("python")
.map(|o| &o.assert_enum_fields)
.unwrap_or(&EMPTY)
}
pub(super) fn resolve_handle_nested_types(e2e_config: &E2eConfig) -> &HashMap<String, String> {
static EMPTY: std::sync::LazyLock<HashMap<String, String>> = std::sync::LazyLock::new(HashMap::new);
e2e_config
.call
.overrides
.get("python")
.map(|o| &o.handle_nested_types)
.unwrap_or(&EMPTY)
}
pub(super) fn resolve_handle_dict_types(e2e_config: &E2eConfig) -> &HashSet<String> {
static EMPTY: std::sync::LazyLock<HashSet<String>> = std::sync::LazyLock::new(HashSet::new);
e2e_config
.call
.overrides
.get("python")
.map(|o| &o.handle_dict_types)
.unwrap_or(&EMPTY)
}
pub(super) fn is_skipped(fixture: &Fixture, language: &str) -> bool {
fixture.skip.as_ref().is_some_and(|s| s.should_skip(language))
}
pub(super) enum BytesKind {
FilePath,
InlineText,
Base64,
}
pub(super) fn classify_bytes_value(s: &str) -> BytesKind {
if s.starts_with('<') || s.starts_with('{') || s.starts_with('[') || s.contains(' ') {
return BytesKind::InlineText;
}
let first = s.chars().next().unwrap_or('\0');
if first.is_ascii_alphanumeric() || first == '_' {
if let Some(slash_pos) = s.find('/') {
if slash_pos > 0 {
let after_slash = &s[slash_pos + 1..];
if after_slash.contains('.') && !after_slash.is_empty() {
return BytesKind::FilePath;
}
}
}
}
BytesKind::Base64
}
pub(super) fn python_method_helper_import(method_name: &str) -> Option<String> {
match method_name {
"has_error_nodes" => Some("tree_has_error_nodes".to_string()),
"error_count" | "tree_error_count" => Some("tree_error_count".to_string()),
"tree_to_sexp" => Some("tree_to_sexp".to_string()),
"contains_node_type" => Some("tree_contains_node_type".to_string()),
"find_nodes_by_type" => Some("find_nodes_by_type".to_string()),
"run_query" => Some("run_query".to_string()),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn classify_bytes_value_html_is_inline() {
matches!(classify_bytes_value("<!DOCTYPE html>"), BytesKind::InlineText);
}
#[test]
fn classify_bytes_value_pdf_path_is_file_path() {
matches!(classify_bytes_value("pdf/fake_memo.pdf"), BytesKind::FilePath);
}
#[test]
fn classify_bytes_value_base64_is_base64() {
matches!(classify_bytes_value("/9j/4AAQSkZJRgABAQEASABIAAD"), BytesKind::Base64);
}
#[test]
fn python_method_helper_import_recognizes_has_error_nodes() {
assert_eq!(
python_method_helper_import("has_error_nodes"),
Some("tree_has_error_nodes".to_string())
);
}
#[test]
fn python_method_helper_import_returns_none_for_plain_method() {
assert!(python_method_helper_import("root_child_count").is_none());
}
}