Files
windmill/backend/windmill-macros/tests/annotations.rs
2025-12-16 19:07:19 +02:00

276 lines
8.1 KiB
Rust

#[cfg(test)]
mod annotations_tests {
extern crate windmill_macros;
use itertools::Itertools;
// use pep440_rs::Version;
use windmill_macros::annotations;
// Previous implementation.
// We have to make sure that new one works the same as old one
fn old(inner_content: &str) -> Annotations {
let annotations = inner_content
.lines()
.take_while(|x| x.starts_with("#"))
.map(|x| x.to_string().replace("#", "").trim().to_string())
.collect_vec();
let ann1: bool = annotations.contains(&"ann1".to_string());
let ann2: bool = annotations.contains(&"ann2".to_string());
let ann3: bool = annotations.contains(&"ann3".to_string());
let ann4: bool = annotations.contains(&"ann4".to_string());
let ann5: bool = annotations.contains(&"ann5".to_string());
Annotations { ann1, ann2, ann3, ann4, ann5 }
}
#[annotations("#")]
#[derive(Eq, PartialEq)]
pub struct Annotations {
pub ann1: bool,
pub ann2: bool,
pub ann3: bool,
pub ann4: bool,
pub ann5: bool,
}
#[annotations("//")]
#[derive(Eq, PartialEq)]
pub struct SlashedAnnotations {
pub ann1: bool,
pub ann2: bool,
pub ann3: bool,
pub ann4: bool,
}
#[annotations("--")]
#[derive(Eq, PartialEq)]
pub struct MinusedAnnotations {
pub ann1: bool,
pub ann2: bool,
}
// e.g. rust, TS and JS
#[test]
fn slashed_annotations() {
let cont = "// ann1
// ann2
//ann3";
assert_eq!(
SlashedAnnotations { ann1: true, ann2: true, ann3: true, ann4: false },
SlashedAnnotations::parse(cont)
);
}
// e.g. Haskell, SQL
#[test]
fn minused_annotations() {
let cont = "-- ann1
-- ann2";
assert_eq!(
MinusedAnnotations { ann1: true, ann2: true },
MinusedAnnotations::parse(cont)
);
}
#[test]
fn simple_integration() {
let cont = "# ann1";
let expected = Annotations { ann1: true, ..Default::default() };
assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
#[test]
fn multiline_integration() {
let cont = "# ann2
# ann3
# ann4
# ann5
";
let expected = Annotations {
ann1: false,
ann2: true,
ann3: true,
ann4: true,
ann5: true,
//
};
assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
#[test]
fn spacing_integration() {
// First line is ignored
{
let cont = "
# ann2";
let expected = Annotations { ann2: true, ..Default::default() };
// assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
// Wrong spacing for ann3
{
let cont = "# ann2
# ann3";
let expected = Annotations { ann2: true, ..Default::default() };
assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
// Drunk but valid spacing
{
let cont = "#ann1
# ann2";
let expected = Annotations { ann2: true, ann1: true, ..Default::default() };
assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
}
#[test]
fn comments_inbetween_integration() {
let cont = "# ann2
# Just comment, has nothing to do with annotations
# Another comment: ann1 ann2 ann3
# ann4 is not valid annotation
# Actual annotation next line:
# ann5
# ann3
";
let expected = Annotations { ann2: true, ann5: true, ann3: true, ..Default::default() };
// assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
#[test]
fn hash_collision() {
// TODO
}
#[test]
fn non_matching_integration() {
{
let cont = r#" "ann1", ann2 "#;
let expected = Annotations::default();
assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
// Empty
{
let cont = "";
let expected = Annotations::default();
assert_eq!(expected, old(cont));
assert_eq!(expected, Annotations::parse(cont));
}
}
#[test]
fn newline_between() {
let cont = "// ann1
// ann2";
assert_eq!(
SlashedAnnotations { ann1: true, ann2: true, ann3: false, ann4: false },
SlashedAnnotations::parse(cont)
);
}
// // #[derive(serde_derive::Serialize, serde_derive::Deserialize, Eq, PartialEq)]
// // #[annotations("#")]
// // pub struct SerAnnotations {
// // pub ann1: bool,
// // pub stt: String,
// // }
// #[test]
// fn non_bool_1() {
// let cont = r#"#ann1, stt: "hey""#;
// // non-bool take entire line, so you can't have one normal and than parsed.
// let a = SerAnnotations { ann1: false, stt: "".to_owned() };
// assert_eq!(a, SerAnnotations::parse(cont));
// }
// #[test]
// fn non_bool_2() {
// let cont = "#ann1, \n#stt: hey";
// let a = SerAnnotations { ann1: true, stt: "hey".to_owned() };
// assert_eq!(a, SerAnnotations::parse(cont));
// }
// #[test]
// fn non_bool_different_idents() {
// #[derive(serde_derive::Serialize, serde_derive::Deserialize, Eq, PartialEq)]
// #[annotations("#")]
// pub struct A {
// pub s: String,
// }
// assert_eq!(A { s: "hey".to_owned() }, A::parse("#s:hey"));
// assert_eq!(A { s: "hey".to_owned() }, A::parse("#s : hey"));
// assert_eq!(A { s: "hey".to_owned() }, A::parse("#s :hey"));
// assert_eq!(A { s: "hey".to_owned() }, A::parse("#s : hey "));
// assert_eq!(A { s: "hey".to_owned() }, A::parse("# s : hey "));
// assert_eq!(A { s: "".to_owned() }, A::parse(" # s : hey "));
// }
// #[test]
// fn non_bool_unparseable_last() {
// #[derive(serde_derive::Serialize, serde_derive::Deserialize, Eq, PartialEq)]
// #[annotations("#")]
// pub struct A {
// pub v: i32,
// }
// let cont = "#v: 1\n#v: non int";
// let a = A {
// v: 1, // Should still be first, second unparsable one should have no affect on existing values
// };
// assert_eq!(a, A::parse(cont));
// }
// #[test]
// fn non_bool_different_types() {
// #[derive(serde_derive::Serialize, serde_derive::Deserialize, Eq, PartialEq)]
// #[annotations("#")]
// pub struct A {
// pub s: String,
// pub i: i32,
// pub o: Option<String>,
// pub a: Vec<i32>,
// pub v: Option<pep440_rs::Version>, // Custom deser
// pub e: E,
// }
// #[derive(
// serde_derive::Serialize, serde_derive::Deserialize, Eq, PartialEq, Clone, Default, Debug,
// )]
// pub enum E {
// #[default]
// One,
// Two(String),
// Three,
// }
// assert_eq!(
// A {
// s: "foo".to_owned(),
// i: 33,
// o: None,
// a: vec![1, 2, 3],
// v: Some(Version::new([1, 0, 0])),
// e: E::Three
// },
// A::parse(
// "#
// #s: foo
// #i: 33
// #o:
// #a: [1, 2, 3]
// #v: 1.0.0
// #e: Three
// "
// )
// );
// }
}