Skip to content

Commit

Permalink
Add jsonnet helpers for front matter schema's
Browse files Browse the repository at this point in the history
  • Loading branch information
あで committed Apr 17, 2024
1 parent ccb4659 commit f2460bc
Show file tree
Hide file tree
Showing 3 changed files with 291 additions and 6 deletions.
82 changes: 76 additions & 6 deletions fiberplane-templates/fiberplane.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -489,22 +489,92 @@ local notebook = {
* used with the `frontmatter.*` helpers.
*
* @function notebook.Notebook#addFrontMatter
* @param {object} value - Map of frontMatter and frontMatterSchema to add to the notebook.
* @param {object | object[]} value - Map of frontMatter and frontMatterSchema to add to the notebook or an array of such objects
* @returns {notebook.Notebook}
*
* @example notebook.addFrontMatter(
* frontMatter.pagerdutyIncident(pagerduty_frontmatter)
* )
*/
addFrontMatter(value):: self {
frontMatter+: value.frontMatter,
frontMatterSchema+: value.frontMatterSchema,
},

addFrontMatter(value)::
if std.isArray(value) then
std.foldl(
function(nb, v)
nb.addFrontMatter(v),
value,
self
)
else self {
frontMatter+: value.frontMatter,
frontMatterSchema+: value.frontMatterSchema,
},
},
};

local createFrontMatterValueWithSchema(key, value, schemaType, displayName, validatorType='string') =
// Validate the key and value types, and if they are valid return the front matter schema and value
if validate.string('front matter field ' + key + 'key', key) == key &&
validate[validatorType]('front matter field ' + key + 'value', value) == value then
{
frontMatterSchema: [{
key: key,
schema: {
type: schemaType,
displayName: displayName,
},
}],
frontMatter: {
[key]: value,
},
} else {
frontMatterSchema: [],
frontMatter: {},
};
local frontMatter = {
/**
* Creates a number frontmatter value and schema.
*
* @function frontMatter.number
* @param {string} key - The key of the front matter entry
* @param {number} value - Number value of the front matter entry
* @param {string} [displayName="Number"] - The display name of the front matter entry
* @returns {object}
*/
number(key, value, displayName='Number')::
createFrontMatterValueWithSchema(key, value, 'number', displayName, 'number'),
/**
* Creates a string frontmatter value and schema.
*
* @function frontMatter.string
* @param {string} key - The key of the front matter entry
* @param {string} value - String value of the front matter entry
* @param {string} [displayName="String"] - The display name of the front matter entry
* @returns {object}
*/
string(key, value, displayName='String')::
createFrontMatterValueWithSchema(key, value, 'string', displayName),
/**
* Creates a datetime frontmatter value and schema. If incorrect datetime is provided, falls back to string.
*
* @function frontMatter.datetime
* @param {string} key - The key of the front matter entry
* @param {string} value - DateTime value of the front matter entry
* @param {string} [displayName="DateTime"] - The display name of the front matter entry
* @returns {object}
*/
dateTime(key, value, displayName='DateTime')::
createFrontMatterValueWithSchema(key, value, 'date_time', displayName),
/**
* Creates a user frontmatter value and schema.
*
* @function frontMatter.user
* @param {string} key - The key of the front matter entry
* @param {string} value - UUID of the user
* @param {string} [displayName="User"] - The display name of the front matter entry
* @returns {object}
*/
user(key, value, displayName='User')::
createFrontMatterValueWithSchema(key, value, 'user', displayName),
/**
* Creates a PagerDuty Incident frontmatter value and schema.
*
Expand Down
213 changes: 213 additions & 0 deletions fiberplane-templates/src/expand/tests/frontmatter_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
use super::*;
use fiberplane_models::{
front_matter_schemas::{
FrontMatterDateTimeSchema, FrontMatterNumberSchema, FrontMatterSchema,
FrontMatterSchemaEntry, FrontMatterStringSchema, FrontMatterUserSchema,
},
notebooks::front_matter::FrontMatterValue,
};
use pretty_assertions::assert_eq;
use serde_json::Value;

const ARGS: [(&str, Value); 0] = [];

// Test manually adding a single value into the front matter
#[test]
fn expands_add_frontmatter() {
let template = r#"
local fp = import 'fiberplane.libsonnet';
local fm = fp.frontMatter;
fp.notebook.new('Notebook')
.addFrontMatter({
frontMatter: {
key: 42
},
frontMatterSchema: [{
key: 'key',
schema: {
type: 'number',
displayName: 'Number'
},
}]
})
"#;
let output = expand_template(template, ARGS).unwrap();
let expected_schema: FrontMatterSchema = vec![FrontMatterSchemaEntry::builder()
.key("key")
.schema(
FrontMatterNumberSchema::builder()
.display_name("Number")
.build(),
)
.build()]
.into();
assert_eq!(output.front_matter_schema, expected_schema);
let expected_front_matter: BTreeMap<String, FrontMatterValue> =
[("key".to_string(), json!(42).into())].into();
assert_eq!(output.front_matter, expected_front_matter);
}

// Test adding multiple number values into the front matter
#[test]
fn expands_add_frontmatter_number() {
let template = r#"
local fp = import 'fiberplane.libsonnet';
local fm = fp.frontMatter;
fp.notebook.new('Notebook')
.addFrontMatter([
fm.number('number', 42, 'Number of issues'),
fm.number('number-2', 13)
])
"#;
let output = expand_template(template, ARGS).unwrap();
let expected_schema: FrontMatterSchema = vec![
FrontMatterSchemaEntry::builder()
.key("number")
.schema(
FrontMatterNumberSchema::builder()
.display_name("Number of issues")
.build(),
)
.build(),
FrontMatterSchemaEntry::builder()
.key("number-2")
.schema(
FrontMatterNumberSchema::builder()
.display_name("Number")
.build(),
)
.build(),
]
.into();
assert_eq!(output.front_matter_schema, expected_schema);
let expected_front_matter: BTreeMap<String, FrontMatterValue> = [
("number".to_string(), json!(42).into()),
("number-2".to_string(), json!(13).into()),
]
.into();
assert_eq!(output.front_matter, expected_front_matter);
}

// Test adding string field into the front matter
#[test]
fn expands_add_frontmatter_string() {
let template = r#"
local fp = import 'fiberplane.libsonnet';
local fm = fp.frontMatter;
fp.notebook.new('Notebook')
.addFrontMatter([
fm.string('string', 'value', 'A field with string value'),
fm.string('string-2', 'value-2')
])
"#;
let output = expand_template(template, ARGS).unwrap();
let expected_schema: FrontMatterSchema = vec![
FrontMatterSchemaEntry::builder()
.key("string")
.schema(
FrontMatterStringSchema::builder()
.display_name("A field with string value")
.build(),
)
.build(),
FrontMatterSchemaEntry::builder()
.key("string-2")
.schema(
FrontMatterStringSchema::builder()
.display_name("String")
.build(),
)
.build(),
]
.into();
assert_eq!(output.front_matter_schema, expected_schema);
let expected_front_matter: BTreeMap<String, FrontMatterValue> = [
("string".to_string(), json!("value").into()),
("string-2".to_string(), json!("value-2").into()),
]
.into();
assert_eq!(output.front_matter, expected_front_matter);
}

// Test adding datetime field into the front matter
#[test]
fn expands_add_frontmatter_datetime() {
let template = r#"
local fp = import 'fiberplane.libsonnet';
local fm = fp.frontMatter;
fp.notebook.new('Notebook')
.addFrontMatter(
fm.dateTime('datetime', '2021-01-01T00:00:00Z')
)
"#;
let output = expand_template(template, ARGS).unwrap();
let expected_schema: FrontMatterSchema = vec![FrontMatterSchemaEntry::builder()
.key("datetime")
.schema(
FrontMatterDateTimeSchema::builder()
.display_name("DateTime")
.build(),
)
.build()]
.into();
assert_eq!(output.front_matter_schema, expected_schema);
let expected_front_matter: BTreeMap<String, FrontMatterValue> =
[("datetime".to_string(), json!("2021-01-01T00:00:00Z").into())].into();
assert_eq!(output.front_matter, expected_front_matter);
}

// Test adding datetime field with incorrect value into the front matter
#[test]
fn expands_add_frontmatter_datetime_incorrect() {
let template = r#"
local fp = import 'fiberplane.libsonnet';
local fm = fp.frontMatter;
fp.notebook.new('Notebook')
.addFrontMatter([
fm.dateTime('correct', '2021-01-01T00:00:00Z'),
fm.dateTime('incorrect', 'not-a-date'),
])
"#;
let output = expand_template(template, ARGS).unwrap();
if let Some(&FrontMatterValue::DateTime(value)) = output.front_matter.get("correct").as_ref() {
value
} else {
panic!(
"Expected a datetime value, got {}",
output.front_matter.get("incorrect").unwrap()
);
};
// this results in a string field, probably not the expected behavior
// let parsed_value = if let Some(&FrontMatterValue::DateTime(foo)) = output.front_matter.get("incorrect").as_ref() {
// foo
// } else {
// panic!("Expected a datetime value, got {}", output.front_matter.get("incorrect").unwrap());
// };
}

// Test adding user value into the front matter
#[test]
fn expands_add_frontmatter_user() {
let template = r#"
local fp = import 'fiberplane.libsonnet';
local fm = fp.frontMatter;
fp.notebook.new('Notebook')
.addFrontMatter([
fm.user('user', 'base64-encoded-user'),
])
"#;
let output = expand_template(template, ARGS).unwrap();
let expected_schema: FrontMatterSchema = vec![FrontMatterSchemaEntry::builder()
.key("user")
.schema(
FrontMatterUserSchema::builder()
.display_name("User")
.build(),
)
.build()]
.into();
assert_eq!(output.front_matter_schema, expected_schema);
let expected_front_matter: BTreeMap<String, FrontMatterValue> =
[("user".to_string(), json!("base64-encoded-user").into())].into();
assert_eq!(output.front_matter, expected_front_matter);
}
2 changes: 2 additions & 0 deletions fiberplane-templates/src/expand/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod frontmatter_tests;

use super::*;
use crate::types::{TemplateParameter, TemplateParameterType};
use crate::*;
Expand Down

0 comments on commit f2460bc

Please sign in to comment.