use super::parse_art;
use crate::types::{ArtDescriptor, ArtParseError, ArtParseOptions};
use vize_s0::Allocator;
fn parse<'a>(
allocator: &'a Allocator,
source: &'a str,
) -> Result<ArtDescriptor<'a>, ArtParseError> {
parse_art(allocator, source, ArtParseOptions::default())
}
fn variant_shape<'a>(desc: &ArtDescriptor<'a>) -> std::vec::Vec<(&'a str, &'a str)> {
desc.variants.iter().map(|v| (v.name, v.template)).collect()
}
#[test]
fn d1_self_closing_variants_are_empty_variants() {
let allocator = Allocator::new();
let source = include_str!(
"../../tests/fixtures/differential/content-musea-and-css-1e05f9370f2a.art.vue.txt"
);
let desc = parse(&allocator, source).unwrap();
assert_eq!(variant_shape(&desc), [("primary", ""), ("secondary", "")]);
let locs: std::vec::Vec<_> = desc
.variants
.iter()
.map(|v| v.loc.map(|loc| (loc.start, loc.end, loc.start_line)))
.collect();
assert_eq!(locs, [Some((48, 74, 2)), Some((77, 105, 3))]);
}
#[test]
fn d2_spaced_equals_is_an_attribute_value() {
let allocator = Allocator::new();
let source = include_str!(
"../../tests/fixtures/differential/vize-patina-require-title-45a52dcf3b55.art.vue.txt"
);
let desc = parse(&allocator, source).unwrap();
assert_eq!(
(desc.metadata.title, desc.metadata.component),
("Button", Some("./Button.vue"))
);
assert_eq!(desc.variants.len(), 0);
}
#[test]
fn d3_style_inside_art_is_not_an_sfc_style_block() {
let allocator = Allocator::new();
let source = include_str!(
"../../tests/fixtures/differential/vize-maestro-configured-lint-tests-8f44edc047c4.art.vue.txt"
);
let desc = parse(&allocator, source).unwrap();
assert_eq!(desc.metadata.title, "Inline");
assert_eq!(desc.styles.len(), 0);
assert_eq!(desc.variants.len(), 0);
}
#[test]
fn d4_unsplittable_container_reports_the_container_error() {
let allocator = Allocator::new();
let source =
include_str!("../../tests/fixtures/differential/vize-patina-html-66050b9db3b6.art.vue.txt");
let Err(ArtParseError::ParseError { line, message }) = parse(&allocator, source) else {
panic!("expected the container error");
};
assert_eq!(
(line, message.as_str()),
(
1,
"Malformed <article> block: the opening tag is incomplete."
)
);
}
#[test]
fn unterminated_art_is_still_no_art_block() {
let allocator = Allocator::new();
for source in [
"<art>",
"<art title=\"A\">\n<variant name=\"v\"></variant>",
"<art",
] {
assert!(
matches!(parse(&allocator, source), Err(ArtParseError::NoArtBlock)),
"{source:?}"
);
}
}
#[test]
fn commented_out_variants_are_ignored() {
let allocator = Allocator::new();
let source = "<art title=\"A\">\n<!-- <variant name=\"Old\">o</variant> -->\n<variant name=\"New\">n</variant>\n</art>";
let desc = parse(&allocator, source).unwrap();
assert_eq!(variant_shape(&desc), [("New", "n")]);
}
#[test]
fn art_block_is_found_by_block_structure() {
let allocator = Allocator::new();
let source = "<script setup>\nconst s = \"<art title='x'></art>\";\n</script>\n<template><article>t</article></template>\n<art title=\"Inline\">\n<variant name=\"v\">x</variant>\n</art>";
let desc = parse(&allocator, source).unwrap();
assert_eq!(desc.metadata.title, "Inline");
assert_eq!(variant_shape(&desc), [("v", "x")]);
assert_eq!(
desc.script_setup.map(|script| script.content),
Some("const s = \"<art title='x'></art>\";")
);
}
#[test]
fn attribute_values_follow_html_syntax() {
let allocator = Allocator::new();
let source = "<art description=\"a > b, not title=x\" title=T>\n<variant name=a/b args='{\"k\": \"the default\"}'>x</variant>\n</art>";
let desc = parse(&allocator, source).unwrap();
assert_eq!(
(desc.metadata.title, desc.metadata.description),
("T", Some("a > b, not title=x"))
);
assert_eq!(variant_shape(&desc), [("a/b", "x")]);
assert!(!desc.variants[0].is_default);
assert_eq!(desc.variants[0].args.len(), 1);
assert_eq!(
desc.variants[0].args.get("k"),
Some(&serde_json::json!("the default"))
);
}
#[test]
fn unquoted_slash_in_the_art_open_tag_is_a_splitter_limitation() {
let allocator = Allocator::new();
let source = "<art title=T component=./Button.vue>\n<variant name=\"v\">x</variant>\n</art>";
assert!(matches!(
parse(&allocator, source),
Err(ArtParseError::NoArtBlock)
));
}
#[test]
fn crlf_after_tag_names_is_whitespace() {
let allocator = Allocator::new();
let source = "<art\r\n title=\"A\">\r\n<variant\r\n name=\"v\">x</variant >\r\n</art>\r\n";
let desc = parse(&allocator, source).unwrap();
assert_eq!(desc.metadata.title, "A");
assert_eq!(variant_shape(&desc), [("v", "x")]);
}