aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2022-03-26 19:57:57 -0600
committerMelody Horn <melody@boringcactus.com>2022-03-26 19:57:57 -0600
commit26a20cf4f3a71ccdd7c6abb06cffd4c12d08395e (patch)
tree046d933b8847545a7bf392a250d3305c031bc344 /tests
parent6f5772173e49f198a18652454ead2a02f8a942af (diff)
downloadkdl-schema-26a20cf4f3a71ccdd7c6abb06cffd4c12d08395e.tar.gz
kdl-schema-26a20cf4f3a71ccdd7c6abb06cffd4c12d08395e.zip
parse schemas with knuffel
Diffstat (limited to 'tests')
-rw-r--r--tests/kdl-schema.kdl373
-rw-r--r--tests/schema-via-knuffel.rs63
2 files changed, 436 insertions, 0 deletions
diff --git a/tests/kdl-schema.kdl b/tests/kdl-schema.kdl
new file mode 100644
index 0000000..4315199
--- /dev/null
+++ b/tests/kdl-schema.kdl
@@ -0,0 +1,373 @@
+document {
+ info {
+ title "KDL Schema" lang="en"
+ description "KDL Schema KDL schema in KDL" lang="en"
+ author "Kat Marchán" {
+ link "https://github.com/zkat" rel="self"
+ }
+ contributor "Lars Willighagen" {
+ link "https://github.com/larsgw" rel="self"
+ }
+ link "https://github.com/zkat/kdl" rel="documentation"
+ license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx="CC-BY-SA-4.0" {
+ link "https://creativecommons.org/licenses/by-sa/4.0/" lang="en"
+ }
+ published "2021-08-31"
+ modified "2021-09-01"
+ }
+ node "document" {
+ min 1
+ max 1
+ children id="node-children" {
+ node "node-names" id="node-names-node" description="Validations to apply specifically to arbitrary node names" {
+ children ref=r#"[id="validations"]"#
+ }
+ node "other-nodes-allowed" id="other-nodes-allowed-node" description="Whether to allow child nodes other than the ones explicitly listed. Defaults to 'false'." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "boolean"
+ }
+ }
+ node "tag-names" description="Validations to apply specifically to arbitrary type tag names" {
+ children ref=r#"[id="validations"]"#
+ }
+ node "other-tags-allowed" description="Whether to allow child node tags other than the ones explicitly listed. Defaults to 'false'." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "boolean"
+ }
+ }
+ node "info" description="A child node that describes the schema itself." {
+ children {
+ node "title" description="The title of the schema or the format it describes" {
+ value description="The title text" {
+ type "string"
+ min 1
+ max 1
+ }
+ prop "lang" id="info-lang" description="The language of the text" {
+ type "string"
+ }
+ }
+ node "description" description="A description of the schema or the format it describes" {
+ value description="The description text" {
+ type "string"
+ min 1
+ max 1
+ }
+ prop ref=r#"[id="info-lang"]"#
+ }
+ node "author" description="Author of the schema" {
+ value id="info-person-name" description="Person name" {
+ type "string"
+ min 1
+ max 1
+ }
+ prop "orcid" id="info-orcid" description="The ORCID of the person" {
+ type "string"
+ pattern r"\d{4}-\d{4}-\d{4}-\d{4}"
+ }
+ children {
+ node ref=r#"[id="info-link"]"#
+ }
+ }
+ node "contributor" description="Contributor to the schema" {
+ value ref=r#"[id="info-person-name"]"#
+ prop ref=r#"[id="info-orcid"]"#
+ }
+ node "link" id="info-link" description="Links to itself, and to sources describing it" {
+ value description="A URL that the link points to" {
+ type "string"
+ format "url" "irl"
+ min 1
+ max 1
+ }
+ prop "rel" description="The relation between the current entity and the URL" {
+ type "string"
+ enum "self" "documentation"
+ }
+ prop ref=r#"[id="info-lang"]"#
+ }
+ node "license" description="The license(s) that the schema is licensed under" {
+ value description="Name of the used license" {
+ type "string"
+ min 1
+ max 1
+ }
+ prop "spdx" description="An SPDX license identifier" {
+ type "string"
+ }
+ children {
+ node ref=r#"[id="info-link"]"#
+ }
+ }
+ node "published" description="When the schema was published" {
+ value description="Publication date" {
+ type "string"
+ format "date"
+ min 1
+ max 1
+ }
+ prop "time" id="info-time" description="A time to accompany the date" {
+ type "string"
+ format "time"
+ }
+ }
+ node "modified" description="When the schema was last modified" {
+ value description="Modification date" {
+ type "string"
+ format "date"
+ min 1
+ max 1
+ }
+ prop ref=r#"[id="info-time"]"#
+ }
+ node "version" description="The version number of this version of the schema" {
+ value description="Semver version number" {
+ type "string"
+ pattern r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
+ min 1
+ max 1
+ }
+ }
+ }
+ }
+ node "tag" id="tag-node" description="A tag belonging to a child node of `document` or another node." {
+ value description="The name of the tag. If a tag name is not supplied, the node rules apply to _all_ nodes belonging to the parent." {
+ type "string"
+ max 1
+ }
+ prop "description" description="A description of this node's purpose." {
+ type "string"
+ }
+ prop "id" description="A globally-unique ID for this node." {
+ type "string"
+ }
+ prop "ref" description="A globally unique reference to another node." {
+ type "string"
+ format "kdl-query"
+ }
+ children {
+ node ref=r#"[id="node-names-node"]"#
+ node ref=r#"[id="other-nodes-allowed-node"]"#
+ node ref=r#"[id="node-node"]"#
+ }
+ }
+ node "node" id="node-node" description="A child node belonging either to `document` or to another `node`. Nodes may be anonymous." {
+ value description="The name of the node. If a node name is not supplied, the node rules apply to _all_ nodes belonging to the parent." {
+ type "string"
+ max 1
+ }
+ prop "description" description="A description of this node's purpose." {
+ type "string"
+ }
+ prop "id" description="A globally-unique ID for this node." {
+ type "string"
+ }
+ prop "ref" description="A globally unique reference to another node." {
+ type "string"
+ format "kdl-query"
+ }
+ children {
+ node "prop-names" description="Validations to apply specifically to arbitrary property names" {
+ children ref=r#"[id="validations"]"#
+ }
+ node "other-props-allowed" description="Whether to allow properties other than the ones explicitly listed. Defaults to 'false'." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "boolean"
+ }
+ }
+ node "min" description="minimum number of instances of this node in its parent's children." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ node "max" description="maximum number of instances of this node in its parent's children." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ node ref=r#"[id="value-tag-node"]"#
+ node "prop" id="prop-node" description="A node property key/value pair." {
+ value description="The property key." {
+ type "string"
+ }
+ prop "id" description="A globally-unique ID of this property." {
+ type "string"
+ }
+ prop "ref" description="A globally unique reference to another property node." {
+ type "string"
+ format "kdl-query"
+ }
+ prop "description" description="A description of this property's purpose." {
+ type "string"
+ }
+ children description="Property-specific validations." {
+ node "required" description="Whether this property is required if its parent is present." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "boolean"
+ }
+ }
+ }
+ children id="validations" description="General value validations." {
+ node "tag" id="value-tag-node" description="The tags associated with this value" {
+ max 1
+ children ref=r#"[id="validations"]"#
+ }
+ node "type" description="The type for this prop's value." {
+ max 1
+ value {
+ min 1
+ type "string"
+ }
+ }
+ node "enum" description="An enumeration of possible values" {
+ max 1
+ value description="Enumeration choices" {
+ min 1
+ }
+ }
+ node "pattern" description="PCRE (Regex) pattern or patterns to test prop values against." {
+ value {
+ min 1
+ type "string"
+ }
+ }
+ node "min-length" description="Minimum length of prop value, if it's a string." {
+ max 1
+ value {
+ min 1
+ type "number"
+ }
+ }
+ node "max-length" description="Maximum length of prop value, if it's a string." {
+ max 1
+ value {
+ min 1
+ type "number"
+ }
+ }
+ node "format" description="Intended data format." {
+ max 1
+ value {
+ min 1
+ type "string"
+ // https://json-schema.org/understanding-json-schema/reference/string.html#format
+ enum "date-time" "date" "time" "duration" "decimal" "currency" "country-2" "country-3" "country-subdivision" "email" "idn-email" "hostname" "idn-hostname" "ipv4" "ipv6" "url" "url-reference" "irl" "irl-reference" "url-template" "regex" "uuid" "kdl-query" "i8" "i16" "i32" "i64" "u8" "u16" "u32" "u64" "isize" "usize" "f32" "f64" "decimal64" "decimal128"
+ }
+ }
+ node "%" description="Only used for numeric values. Constrains them to be multiples of the given number(s)" {
+ max 1
+ value {
+ min 1
+ type "number"
+ }
+ }
+ node ">" description="Only used for numeric values. Constrains them to be greater than the given number(s)" {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ node ">=" description="Only used for numeric values. Constrains them to be greater than or equal to the given number(s)" {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ node "<" description="Only used for numeric values. Constrains them to be less than the given number(s)" {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ node "<=" description="Only used for numeric values. Constrains them to be less than or equal to the given number(s)" {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ }
+ }
+ node "value" id="value-node" description="one or more direct node values" {
+ prop "id" description="A globally-unique ID of this value." {
+ type "string"
+ }
+ prop "ref" description="A globally unique reference to another value node." {
+ type "string"
+ format "kdl-query"
+ }
+ prop "description" description="A description of this property's purpose." {
+ type "string"
+ }
+ children ref=r#"[id="validations"]"#
+ children description="Node value-specific validations" {
+ node "min" description="minimum number of values for this node." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ node "max" description="maximum number of values for this node." {
+ max 1
+ value {
+ min 1
+ max 1
+ type "number"
+ }
+ }
+ }
+ }
+ node "children" id="children-node" {
+ prop "id" description="A globally-unique ID of this children node." {
+ type "string"
+ }
+ prop "ref" description="A globally unique reference to another children node." {
+ type "string"
+ format "kdl-query"
+ }
+ prop "description" description="A description of this these children's purpose." {
+ type "string"
+ }
+ children ref=r#"[id="node-children"]"#
+ }
+ }
+ }
+ node "definitions" description="Definitions to reference in parts of the top-level nodes" {
+ children {
+ node ref=r#"[id="node-node"]"#
+ node ref=r#"[id="value-node"]"#
+ node ref=r#"[id="prop-node"]"#
+ node ref=r#"[id="children-node"]"#
+ node ref=r#"[id="tag-node"]"#
+ }
+ }
+ }
+ }
+}
diff --git a/tests/schema-via-knuffel.rs b/tests/schema-via-knuffel.rs
new file mode 100644
index 0000000..b0d1a1c
--- /dev/null
+++ b/tests/schema-via-knuffel.rs
@@ -0,0 +1,63 @@
+#![cfg(feature = "knuffel")]
+
+use std::fmt::Debug;
+
+use kdl_schema::*;
+
+trait DeepAssertEq
+where
+ Self: PartialEq + Debug,
+{
+ fn deep_assert_eq(left: &Self, right: &Self) {
+ assert_eq!(left, right);
+ }
+}
+
+impl DeepAssertEq for Schema {
+ fn deep_assert_eq(left: &Self, right: &Self) {
+ DeepAssertEq::deep_assert_eq(&left.document, &right.document)
+ }
+}
+
+impl DeepAssertEq for Document {
+ fn deep_assert_eq(left: &Self, right: &Self) {
+ DeepAssertEq::deep_assert_eq(&left.info, &right.info);
+ DeepAssertEq::deep_assert_eq(&left.nodes, &right.nodes);
+ }
+}
+
+impl<T: DeepAssertEq> DeepAssertEq for Vec<T> {
+ fn deep_assert_eq(left: &Self, right: &Self) {
+ for (left, right) in left.iter().zip(right.iter()) {
+ DeepAssertEq::deep_assert_eq(left, right);
+ }
+ assert_eq!(left, right);
+ }
+}
+
+impl DeepAssertEq for Info {}
+
+impl DeepAssertEq for Node {
+ fn deep_assert_eq(left: &Self, right: &Self) {
+ DeepAssertEq::deep_assert_eq(&left.props, &right.props);
+ DeepAssertEq::deep_assert_eq(&left.values, &right.values);
+ DeepAssertEq::deep_assert_eq(&left.children, &right.children);
+ assert_eq!(left, right);
+ }
+}
+
+impl DeepAssertEq for node::Prop {}
+impl DeepAssertEq for node::Value {}
+impl DeepAssertEq for node::Children {
+ fn deep_assert_eq(left: &Self, right: &Self) {
+ DeepAssertEq::deep_assert_eq(&left.nodes, &right.nodes);
+ assert_eq!(left, right);
+ }
+}
+
+#[test]
+fn schema_loads() -> miette::Result<()> {
+ let schema: Schema = knuffel::parse("kdl-schema.kdl", include_str!("kdl-schema.kdl"))?;
+ DeepAssertEq::deep_assert_eq(&schema, &*SCHEMA_SCHEMA);
+ Ok(())
+}