mirror of https://github.com/kdl-org/kdl-rs.git
162 lines
5.1 KiB
Rust
162 lines
5.1 KiB
Rust
//! Tests the kdl files in the examples directory.
|
|
|
|
use kdl::*;
|
|
use std::collections::HashMap;
|
|
|
|
/// Helper for constructing nodes.
|
|
///
|
|
/// This takes input that's similar to KDL itself, but each node must be terminated with either
|
|
/// a semicolon or a braced block. Nodes whose name contains characters not valid in Rust
|
|
/// identifiers must be written as a string literal instead.
|
|
macro_rules! nodes {
|
|
([$v:ident]:name) => {};
|
|
([$v:ident]:name $name:ident $($tt:tt)*) => {
|
|
nodes!([$v]:values stringify!($name); {} {} $($tt)*)
|
|
};
|
|
([$v:ident]:name $name:literal $($tt:tt)*) => {
|
|
nodes!([$v]:values $name; {} {} $($tt)*)
|
|
};
|
|
([$v:ident]:values $name:expr; {$($value:literal,)*} $props:tt $new_value:literal $($tt:tt)*) => {
|
|
nodes!([$v]:values $name; {$($value,)* $new_value,} $props $($tt)*)
|
|
};
|
|
([$v:ident]:values $name:expr; $values:tt {$($key:ident=$prop:literal,)*} $new_key:ident=$new_prop:literal $($tt:tt)*) => {
|
|
nodes!([$v]:values $name; $values {$($key=$prop,)* $new_key=$new_prop,} $($tt)*)
|
|
};
|
|
([$v:ident]:values $name:expr; $values:tt $props:tt $(; $($tt:tt)*)?) => {
|
|
nodes!([$v]:values $name; $values $props {} $($($tt)*)?)
|
|
};
|
|
([$v:ident]:values $name:expr; {$($value:literal,)*} {$($key:ident=$prop:literal,)*} {$($child:tt)*} $($tail:tt)*) => {
|
|
$v.push(KdlNode {
|
|
name: $name.to_owned(),
|
|
values: vec![$( $value.to_owned().into() ),*],
|
|
properties: {
|
|
#[allow(unused_mut)]
|
|
let mut map = HashMap::new();
|
|
$(
|
|
map.insert(stringify!($key).to_owned(), $prop.to_owned().into());
|
|
)*
|
|
map
|
|
},
|
|
children: nodes!($($child)*),
|
|
});
|
|
nodes!([$v]:name $($tail)*);
|
|
};
|
|
// Explicitly match literal and ident at the start instead of $($tt:tt)*
|
|
// so we get better errors than "recursion limit exceeded" if we fail to match.
|
|
(:start $($tt:tt)+) => {{
|
|
let mut v = Vec::new();
|
|
nodes!([v]:name $($tt)+);
|
|
v
|
|
}};
|
|
($name:literal $($tt:tt)*) => {
|
|
nodes!(:start $name $($tt)*)
|
|
};
|
|
($name:ident $($tt:tt)*) => {
|
|
nodes!(:start $name $($tt)*)
|
|
};
|
|
() => { vec![] }
|
|
}
|
|
|
|
const NUMBERS: &str = r#"
|
|
hex 0x32;
|
|
float 0.5;
|
|
binary 0b0110;
|
|
octal 0o755;
|
|
bignum 1_000_000;
|
|
scientific 1.234e-10;
|
|
"#;
|
|
|
|
#[test]
|
|
fn test_numbers() {
|
|
let doc = parse_document(NUMBERS);
|
|
assert_eq!(
|
|
doc,
|
|
Ok(nodes! {
|
|
hex 0x32;
|
|
float 0.5;
|
|
binary 0b0110;
|
|
octal 0o755;
|
|
bignum 1_000_000;
|
|
scientific 1.234e-10;
|
|
})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_ci() {
|
|
let doc = parse_document(include_str!("../examples/ci.kdl"));
|
|
let nodes = nodes! {
|
|
name "CI";
|
|
on "push" "pull_request";
|
|
env {
|
|
RUSTFLAGS "-Dwarnings"
|
|
}
|
|
jobs {
|
|
fmt_and_docs "Check fmt & build docs" {
|
|
"runs-on" "ubuntu-latest";
|
|
steps {
|
|
step uses="actions/checkout@v1";
|
|
step "Install Rust" uses="actions-rs/toolchain@v1" {
|
|
profile "minimal";
|
|
toolchain "stable";
|
|
components "rustfmt";
|
|
override true;
|
|
}
|
|
step "rustfmt" run="cargo fmt --all -- --check";
|
|
step "docs" run="cargo doc --no-deps";
|
|
}
|
|
}
|
|
build_and_test "Build & Test" {
|
|
"runs-on" "${{ matrix.os }}";
|
|
strategy {
|
|
matrix {
|
|
rust "1.46.0" "stable";
|
|
os "ubuntu-latest" "macOS-latest" "windows-latest";
|
|
}
|
|
}
|
|
|
|
steps {
|
|
step uses="actions/checkout@v1";
|
|
step "Install Rust" uses="actions-rs/toolchain@v1" {
|
|
profile "minimal";
|
|
toolchain "${{ matrix.rust }}";
|
|
components "clippy";
|
|
override true;
|
|
}
|
|
step "Clippy" run="cargo clippy --all -- -D warnings";
|
|
step "Run tests" run="cargo test --all --verbose";
|
|
}
|
|
}
|
|
}
|
|
};
|
|
assert_eq!(doc, Ok(nodes));
|
|
}
|
|
|
|
#[test]
|
|
fn test_cargo() {
|
|
let doc = parse_document(include_str!("../examples/Cargo.kdl"));
|
|
let nodes = nodes! {
|
|
package {
|
|
name "kdl";
|
|
version "0.0.0";
|
|
description "kat's document language";
|
|
authors "Kat Marchán <kzm@zkat.tech>";
|
|
"license-file" "LICENSE.md";
|
|
edition "2018";
|
|
}
|
|
dependencies {
|
|
nom "6.0.1";
|
|
thiserror "1.0.22";
|
|
}
|
|
};
|
|
assert_eq!(doc, Ok(nodes));
|
|
}
|
|
|
|
#[test]
|
|
fn test_nuget() {
|
|
let doc = parse_document(include_str!("../examples/nuget.kdl"));
|
|
// This file is particularly large. It would be nice to validate it, but for now
|
|
// I'm just going to settle for making sure it parses.
|
|
doc.expect("Parsing failed");
|
|
}
|