wick_config/config/
test_config.rs

1#![allow(missing_docs)] // delete when we move away from the `property` crate.
2use std::collections::HashMap;
3use std::path::{Path, PathBuf};
4
5use asset_container::AssetManager;
6use tracing::trace;
7use wick_packet::{InherentData, RuntimeConfig};
8
9use super::template_config::Renderable;
10use super::LiquidJsonConfig;
11use crate::config::test_case;
12use crate::error::ManifestError;
13
14#[derive(
15  Debug, Clone, derive_builder::Builder, derive_asset_container::AssetManager, property::Property, serde::Serialize,
16)]
17#[property(get(public), set(public), mut(public, suffix = "_mut"))]
18#[asset(asset(crate::config::AssetReference))]
19#[must_use]
20/// A Wick tests configuration.
21///
22/// A tests configuration is a collection of shareable and reusable unit tests against wick components and operations.
23pub struct TestConfiguration {
24  /// The name of the tests configuration.
25  #[asset(skip)]
26  #[builder(default)]
27  #[serde(skip_serializing_if = "Option::is_none")]
28  pub(crate) name: Option<String>,
29
30  /// The source (i.e. url or file on disk) of the configuration.
31  #[asset(skip)]
32  #[property(skip)]
33  #[builder(default)]
34  #[serde(skip_serializing_if = "Option::is_none")]
35  pub(crate) source: Option<PathBuf>,
36
37  /// The configuration with which to initialize the component before running tests.
38  #[asset(skip)]
39  #[builder(default)]
40  #[serde(skip_serializing_if = "Option::is_none")]
41  pub(crate) config: Option<LiquidJsonConfig>,
42
43  /// A suite of test cases to run against component operations.
44  #[asset(skip)]
45  #[builder(default)]
46  #[serde(skip_serializing_if = "Vec::is_empty")]
47  pub(crate) cases: Vec<test_case::TestCase>,
48
49  /// The environment this configuration has access to.
50  #[asset(skip)]
51  #[builder(default)]
52  #[serde(skip_serializing_if = "Option::is_none")]
53  pub(crate) env: Option<HashMap<String, String>>,
54}
55
56impl TestConfiguration {
57  /// Set the source location of the configuration.
58  pub fn set_source(&mut self, source: &Path) {
59    let source = source.to_path_buf();
60    self.source = Some(source);
61  }
62
63  pub(super) fn update_baseurls(&self) {
64    #[allow(clippy::expect_used)]
65    let mut source = self.source.clone().expect("No source set for this configuration");
66    // Source is (should be) a file, so pop the filename before setting the baseurl.
67    if !source.is_dir() {
68      source.pop();
69    }
70    self.set_baseurl(&source);
71  }
72
73  /// Validate this configuration is good.
74  #[allow(clippy::missing_const_for_fn)]
75  pub fn validate(&self) -> Result<(), ManifestError> {
76    /* placeholder */
77    Ok(())
78  }
79
80  /// Initialize the configuration, rendering template configuration when possibles.
81  pub fn initialize(&mut self) -> Result<&Self, ManifestError> {
82    let source = self.source.clone();
83
84    trace!(
85      source = ?source,
86      "initializing test configuration"
87    );
88
89    let env = self.env.clone();
90
91    self.render_config(source.as_deref(), None, env.as_ref())?;
92
93    Ok(self)
94  }
95}
96
97impl Renderable for TestConfiguration {
98  fn render_config(
99    &mut self,
100    source: Option<&Path>,
101    root_config: Option<&RuntimeConfig>,
102    env: Option<&HashMap<String, String>>,
103  ) -> Result<(), ManifestError> {
104    if let Some(config) = self.config.as_mut() {
105      config.set_value(Some(config.render(
106        source,
107        root_config,
108        None,
109        env,
110        Some(&InherentData::unsafe_default()),
111      )?));
112    }
113
114    self.cases.render_config(source, root_config, env)?;
115    Ok(())
116  }
117}