Skip to content

Commit 4476e05

Browse files
author
Nichol Yip
committed
- Implement test cases for spec types that has Lints implemented
- Fix how lints are outputted to CLI Signed-off-by: Nichol Yip <[email protected]>
1 parent 798bba3 commit 4476e05

19 files changed

+741
-14
lines changed

crates/spk-schema/src/build_spec.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,10 @@ struct BuildSpecVisitor {
437437

438438
impl Lints for BuildSpecVisitor {
439439
fn lints(&mut self) -> Vec<Lint> {
440+
for lint in self.lints.iter_mut() {
441+
lint.update_key("build");
442+
}
443+
440444
std::mem::take(&mut self.lints)
441445
}
442446
}
@@ -503,11 +507,15 @@ impl<'de> serde::de::Visitor<'de> for BuildSpecVisitor {
503507
"variants" => {
504508
unchecked.raw_variants = map.next_value()?;
505509
}
506-
"validation" => unchecked.validation = map.next_value::<ValidationSpec>()?,
510+
"validation" => {
511+
let linted_validations = map.next_value::<LintedItem<ValidationSpec>>()?;
512+
self.lints.extend(linted_validations.lints);
513+
unchecked.validation = linted_validations.item;
514+
}
507515
"auto_host_vars" => unchecked.auto_host_vars = map.next_value::<AutoHostVars>()?,
508516
unknown_key => {
509517
self.lints.push(Lint::Key(UnknownKey::new(
510-
&format!("build.{unknown_key}"),
518+
&unknown_key,
511519
BuildSpec::FIELD_NAMES_AS_ARRAY.to_vec(),
512520
)));
513521
map.next_value::<serde::de::IgnoredAny>()?;

crates/spk-schema/src/build_spec_test.rs

+125
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use spk_schema_foundation::{option_map, pkg_name, FromYaml, IsDefault};
77

88
use super::{AutoHostVars, BuildSpec};
99
use crate::build_spec::UncheckedBuildSpec;
10+
use crate::LintedItem;
1011

1112
#[rstest]
1213
fn test_auto_host_vars_default() {
@@ -223,3 +224,127 @@ options:
223224
.unwrap();
224225
assert_ne!(build_id1, build_id2);
225226
}
227+
228+
#[rstest]
229+
fn test_build_script_lint() {
230+
let build_spec: LintedItem<UncheckedBuildSpec> = serde_yaml::from_str(
231+
r#"
232+
options:
233+
- var: arch
234+
- var: os
235+
- var: centos
236+
- pkg: python/3
237+
variants:
238+
- {python: 2.7}
239+
- {python: 3.7, gcc: 9.3}
240+
scripts:
241+
- echo "Hello World!"
242+
"#,
243+
)
244+
.unwrap();
245+
246+
assert_eq!(build_spec.lints.len(), 1);
247+
for lint in build_spec.lints.iter() {
248+
assert_eq!(lint.get_key(), "build.scripts");
249+
}
250+
}
251+
252+
#[rstest]
253+
fn test_build_variant_lint() {
254+
let build_spec: LintedItem<UncheckedBuildSpec> = serde_yaml::from_str(
255+
r#"
256+
options:
257+
- var: arch
258+
- var: os
259+
- var: centos
260+
- pkg: python/3
261+
variant:
262+
- {python: 2.7}
263+
- {python: 3.7, gcc: 9.3}
264+
script:
265+
- echo "Hello World!"
266+
"#,
267+
)
268+
.unwrap();
269+
270+
assert_eq!(build_spec.lints.len(), 1);
271+
for lint in build_spec.lints.iter() {
272+
assert_eq!(lint.get_key(), "build.variant");
273+
}
274+
}
275+
276+
#[rstest]
277+
fn test_build_options_lint() {
278+
let build_spec: LintedItem<UncheckedBuildSpec> = serde_yaml::from_str(
279+
r#"
280+
option:
281+
- var: arch
282+
- var: os
283+
- var: centos
284+
- pkg: python/3
285+
variants:
286+
- {python: 2.7}
287+
- {python: 3.7, gcc: 9.3}
288+
script:
289+
- echo "Hello World!"
290+
"#,
291+
)
292+
.unwrap();
293+
294+
assert_eq!(build_spec.lints.len(), 1);
295+
for lint in build_spec.lints.iter() {
296+
assert_eq!(lint.get_key(), "build.option");
297+
}
298+
}
299+
300+
#[rstest]
301+
fn test_build_auto_host_vars_lint() {
302+
let build_spec: LintedItem<UncheckedBuildSpec> = serde_yaml::from_str(
303+
r#"
304+
options:
305+
- var: arch
306+
- var: os
307+
- var: centos
308+
- pkg: python/3
309+
variants:
310+
- {python: 2.7}
311+
- {python: 3.7, gcc: 9.3}
312+
script:
313+
- echo "Hello World!"
314+
auto_host_var: "None"
315+
"#,
316+
)
317+
.unwrap();
318+
319+
assert_eq!(build_spec.lints.len(), 1);
320+
for lint in build_spec.lints.iter() {
321+
assert_eq!(lint.get_key(), "build.auto_host_var");
322+
}
323+
}
324+
325+
#[rstest]
326+
fn test_build_validation_lint() {
327+
let build_spec: LintedItem<UncheckedBuildSpec> = serde_yaml::from_str(
328+
r#"
329+
options:
330+
- var: arch
331+
- var: os
332+
- var: centos
333+
- pkg: python/3
334+
variants:
335+
- {python: 2.7}
336+
- {python: 3.7, gcc: 9.3}
337+
script:
338+
- echo "Hello World!"
339+
validations: {
340+
"rules": [{"allow": "EmptyPackage"}]
341+
}
342+
"#,
343+
)
344+
.unwrap();
345+
346+
assert_eq!(build_spec.lints.len(), 1);
347+
for lint in build_spec.lints.iter() {
348+
assert_eq!(lint.get_key(), "build.validations");
349+
}
350+
}

crates/spk-schema/src/embedded_packages_list.rs

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ struct EmbeddedPackagesListVisitor {
6969

7070
impl Lints for EmbeddedPackagesListVisitor {
7171
fn lints(&mut self) -> Vec<Lint> {
72+
for lint in self.lints.iter_mut() {
73+
lint.update_key("embedded");
74+
}
75+
7276
std::mem::take(&mut self.lints)
7377
}
7478
}

crates/spk-schema/src/embedded_packages_list_test.rs

+54
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use rstest::rstest;
66

77
use super::EmbeddedPackagesList;
8+
use crate::LintedItem;
89

910
#[rstest]
1011
fn test_install_embedded_build_options() {
@@ -45,3 +46,56 @@ fn test_embedded_nested_embedded() {
4546
)
4647
.unwrap();
4748
}
49+
50+
#[rstest]
51+
fn test_embedded_install_lint() {
52+
let _spec: LintedItem<EmbeddedPackagesList> = serde_yaml::from_str(
53+
r#"
54+
- pkg: "embedded/1.0.0"
55+
install:
56+
environments:
57+
- priority: 99
58+
"#,
59+
)
60+
.unwrap();
61+
62+
assert_eq!(_spec.lints.len(), 1);
63+
for lint in _spec.lints.iter() {
64+
assert_eq!(lint.get_key(), "embedded.install.environments")
65+
}
66+
}
67+
68+
#[rstest]
69+
fn test_embedded_components_lint() {
70+
let _spec: LintedItem<EmbeddedPackagesList> = serde_yaml::from_str(
71+
r#"
72+
- pkg: "embedded/1.0.0"
73+
component:
74+
- name: run
75+
embedded:
76+
- pkg: "nested-embedded/2.0.0"
77+
"#,
78+
)
79+
.unwrap();
80+
81+
assert_eq!(_spec.lints.len(), 1);
82+
for lint in _spec.lints.iter() {
83+
assert_eq!(lint.get_key(), "embedded.component")
84+
}
85+
}
86+
87+
#[rstest]
88+
fn test_embedded_build_lint() {
89+
let _spec: LintedItem<EmbeddedPackagesList> = serde_yaml::from_str(
90+
r#"
91+
- pkg: "embedded/1.0.0"
92+
build: {"option": [{"var": "python.abi", "static": "cp37"}]}
93+
"#,
94+
)
95+
.unwrap();
96+
97+
assert_eq!(_spec.lints.len(), 1);
98+
for lint in _spec.lints.iter() {
99+
assert_eq!(lint.get_key(), "embedded.build.option")
100+
}
101+
}

crates/spk-schema/src/install_spec.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ where
6363
{
6464
fn lints(&mut self) -> Vec<Lint> {
6565
self.lints.extend(std::mem::take(&mut self.embedded.lints));
66+
for lint in self.lints.iter_mut() {
67+
lint.update_key("install");
68+
}
69+
6670
std::mem::take(&mut self.lints)
6771
}
6872
}
@@ -260,7 +264,7 @@ where
260264
"environment" => self.environment = map.next_value::<EnvOpList>()?,
261265
unknown_key => {
262266
self.lints.push(Lint::Key(UnknownKey::new(
263-
&format!("install.{unknown_key}"),
267+
&unknown_key,
264268
InstallSpecVisitor::<D>::FIELD_NAMES_AS_ARRAY.to_vec(),
265269
)));
266270
map.next_value::<serde::de::IgnoredAny>()?;

crates/spk-schema/src/install_spec_test.rs

+72-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use spk_schema_foundation::option_map::OptionMap;
1111
use spk_schema_foundation::version::{Version, BINARY_STR};
1212
use spk_schema_ident::{parse_ident_range, PkgRequest, Request, RequestedBy};
1313

14-
use crate::{InstallSpec, Package, RequirementsList};
14+
use crate::{InstallSpec, LintedItem, Package, RawInstallSpec, RequirementsList};
1515

1616
#[rstest]
1717
fn test_render_all_pins_renders_requirements_in_components() {
@@ -280,3 +280,74 @@ embedded:
280280
"expecting embedded to be expanded correctly"
281281
);
282282
}
283+
284+
#[rstest]
285+
fn test_install_spec_lint_component_field() {
286+
let install = serde_yaml::from_str::<LintedItem<RawInstallSpec>>(
287+
r#"
288+
comzponents:
289+
- name: comp1
290+
"#,
291+
)
292+
.unwrap();
293+
294+
assert_eq!(install.lints.len(), 1);
295+
for lint in install.lints.iter() {
296+
assert_eq!(lint.get_key(), "install.comzponents");
297+
}
298+
}
299+
300+
#[rstest]
301+
fn test_install_spec_lint_embedded_field() {
302+
let install = serde_yaml::from_str::<LintedItem<RawInstallSpec>>(
303+
r#"
304+
components:
305+
- name: comp1
306+
embeddsed:
307+
- pkg: "embedded/1.0.0"
308+
install:
309+
components:
310+
- name: comp1
311+
"#,
312+
)
313+
.unwrap();
314+
315+
assert_eq!(install.lints.len(), 1);
316+
for lint in install.lints.iter() {
317+
assert_eq!(lint.get_key(), "install.embeddsed");
318+
}
319+
}
320+
321+
#[rstest]
322+
fn test_install_spec_lint_requirements_field() {
323+
let install = serde_yaml::from_str::<LintedItem<RawInstallSpec>>(
324+
r#"
325+
requirement:
326+
- pkg: stdfs
327+
"#,
328+
)
329+
.unwrap();
330+
331+
assert_eq!(install.lints.len(), 1);
332+
for lint in install.lints.iter() {
333+
assert_eq!(lint.get_key(), "install.requirement");
334+
}
335+
}
336+
337+
#[rstest]
338+
fn test_install_spec_lint_environments_field() {
339+
let install = serde_yaml::from_str::<LintedItem<RawInstallSpec>>(
340+
r#"
341+
environments:
342+
- priority: 99
343+
- set: PYVER1
344+
value: $SPK_PKG_python_VERSION_BASE
345+
"#,
346+
)
347+
.unwrap();
348+
349+
assert_eq!(install.lints.len(), 1);
350+
for lint in install.lints.iter() {
351+
assert_eq!(lint.get_key(), "install.environments");
352+
}
353+
}

crates/spk-schema/src/lints.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl UnknownKey {
2222

2323
pub fn generate_message(&self) -> String {
2424
let key: &str = self.unknown_key.split('.').last().unwrap_or_default();
25-
let mut message = format!("Unrecognized key: {}. ", self.unknown_key);
25+
let mut message = format!("Unrecognized key: {} ", self.unknown_key);
2626
let mut corpus = CorpusBuilder::new().finish();
2727

2828
for field in self.struct_fields.iter() {
@@ -31,7 +31,7 @@ impl UnknownKey {
3131

3232
match corpus.search(key, 0.6).first() {
3333
Some(s) => message.push_str(format!("(Did you mean: '{}'?)", s.text).as_str()),
34-
None => message.push_str(format!("(No similar keys found for: {}.)", key).as_str()),
34+
None => message.push_str(format!("(No similar keys found for: {})", key).as_str()),
3535
};
3636

3737
message.to_string()
@@ -43,6 +43,20 @@ pub enum Lint {
4343
Key(UnknownKey),
4444
}
4545

46+
impl Lint {
47+
pub fn get_key(&self) -> &str {
48+
match self {
49+
Lint::Key(k) => &k.unknown_key,
50+
}
51+
}
52+
53+
pub fn update_key(&mut self, key: &str) {
54+
match self {
55+
Lint::Key(k) => k.unknown_key = format!("{key}.{}", k.unknown_key),
56+
}
57+
}
58+
}
59+
4660
#[derive(Debug, Default, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
4761
pub struct LintedItem<T> {
4862
pub item: T,

0 commit comments

Comments
 (0)