#![allow(dead_code, deprecated)]
use indexmap::{IndexMap, IndexSet};
use schematic::schema::template::TemplateOptions;
use schematic::schema::SchemaGenerator;
use schematic::*;
use starbase_sandbox::{assert_snapshot, create_empty_sandbox};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
derive_enum!(
#[derive(ConfigEnum, Default)]
pub enum BasicEnum {
#[default]
Foo,
Bar,
Baz,
}
);
#[derive(Clone, Config)]
pub struct AnotherConfig {
opt: Option<String>,
enums: Option<BasicEnum>,
}
#[derive(Clone, Config)]
struct GenConfig {
boolean: bool,
string: String,
number: usize,
float32: f32,
float64: f64,
vector: Vec<String>,
map: HashMap<String, u64>,
enums: BasicEnum,
#[setting(nested)]
nested: AnotherConfig,
date: chrono::NaiveDate,
datetime: chrono::NaiveDateTime,
decimal: rust_decimal::Decimal,
time: chrono::NaiveTime,
path: PathBuf,
rel_path: relative_path::RelativePathBuf,
url: Option<url::Url>,
version: Option<semver::Version>,
version_req: semver::VersionReq,
json_value: serde_json::Value,
toml_value: Option<toml::Value>,
yaml_value: serde_yaml::Value,
indexmap: IndexMap<String, String>,
indexset: Option<IndexSet<String>>,
}
#[derive(Clone, Config)]
#[config(env_prefix = "ENV_PREFIX_")]
pub struct TwoDepthConfig {
opt: Option<String>,
skipped: String,
}
#[derive(Clone, Config)]
pub struct OneDepthConfig {
#[setting(nested)]
two: TwoDepthConfig,
#[setting(skip)]
skipped: String,
}
#[derive(Clone, Config)]
struct TemplateConfig {
#[setting(env = "TEMPLATE_BOOLEAN")]
boolean: bool,
#[setting(default = "abc")]
string: String,
number: usize,
#[deprecated]
float32: f32,
#[setting(default = 1.23)]
float64: f64,
vector: Vec<String>,
map: HashMap<String, u64>,
#[deprecated = "Dont use enums!"]
enums: BasicEnum,
#[setting(nested)]
nested: AnotherConfig,
#[setting(nested)]
one: OneDepthConfig,
skipped: String,
#[setting(nested)]
expand_array: Vec<AnotherConfig>,
expand_array_primitive: Vec<usize>,
#[setting(nested)]
expand_object: HashMap<String, AnotherConfig>,
expand_object_primitive: HashMap<String, usize>,
}
fn create_generator() -> SchemaGenerator {
let mut generator = SchemaGenerator::default();
generator.add::<GenConfig>();
generator
}
fn create_template_generator() -> SchemaGenerator {
let mut generator = SchemaGenerator::default();
generator.add::<TemplateConfig>();
generator
}
fn create_template_options() -> TemplateOptions {
TemplateOptions {
comment_fields: vec!["float32".into(), "map".into()],
expand_fields: vec![
"expandArray".into(),
"expandArrayPrimitive".into(),
"expandObject".into(),
"expandObjectPrimitive".into(),
],
hide_fields: vec!["skipped".into(), "one.two.skipped".into()],
..TemplateOptions::default()
}
}
#[cfg(feature = "renderer_json_schema")]
mod json_schema {
use super::*;
use schematic::schema::json_schema::*;
#[test]
fn defaults() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.json");
create_generator()
.generate(&file, JsonSchemaRenderer::default())
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
#[test]
fn not_required() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.json");
create_generator()
.generate(
&file,
JsonSchemaRenderer::new(JsonSchemaOptions {
mark_struct_fields_required: false,
..JsonSchemaOptions::default()
}),
)
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
#[test]
fn with_titles() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.json");
create_generator()
.generate(
&file,
JsonSchemaRenderer::new(JsonSchemaOptions {
set_field_name_as_title: true,
..JsonSchemaOptions::default()
}),
)
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
#[test]
fn with_markdown_descs() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.json");
create_generator()
.generate(
&file,
JsonSchemaRenderer::new(JsonSchemaOptions {
markdown_description: true,
..JsonSchemaOptions::default()
}),
)
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
}
#[cfg(all(feature = "renderer_template", feature = "json"))]
mod template_json {
use super::*;
use schematic::schema::*;
#[test]
fn defaults() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.json");
create_template_generator()
.generate(&file, JsoncTemplateRenderer::new(create_template_options()))
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
#[test]
fn without_comments() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.json");
create_template_generator()
.generate(&file, JsonTemplateRenderer::new(create_template_options()))
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
}
#[cfg(all(feature = "renderer_template", feature = "toml"))]
mod template_toml {
use super::*;
use schematic::schema::*;
#[test]
fn defaults() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.toml");
create_template_generator()
.generate(&file, TomlTemplateRenderer::new(create_template_options()))
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
}
#[cfg(all(feature = "renderer_template", feature = "yaml"))]
mod template_yaml {
use super::*;
use schematic::schema::*;
#[test]
fn defaults() {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("schema.yaml");
create_template_generator()
.generate(&file, YamlTemplateRenderer::new(create_template_options()))
.unwrap();
assert_snapshot!(fs::read_to_string(file).unwrap());
}
}
#[cfg(feature = "renderer_typescript")]
mod typescript {
use super::*;
use schematic::schema::typescript::*;
fn generate(options: TypeScriptOptions) -> String {
let sandbox = create_empty_sandbox();
let file = sandbox.path().join("types.ts");
create_generator()
.generate(&file, TypeScriptRenderer::new(options))
.unwrap();
fs::read_to_string(file).unwrap()
}
#[test]
fn defaults() {
assert_snapshot!(generate(TypeScriptOptions::default()));
}
#[test]
fn enums() {
assert_snapshot!(generate(TypeScriptOptions {
enum_format: EnumFormat::Enum,
..TypeScriptOptions::default()
}));
}
#[test]
fn value_enums() {
assert_snapshot!(generate(TypeScriptOptions {
enum_format: EnumFormat::ValuedEnum,
..TypeScriptOptions::default()
}));
}
#[test]
fn const_enums() {
assert_snapshot!(generate(TypeScriptOptions {
const_enum: true,
enum_format: EnumFormat::Enum,
..TypeScriptOptions::default()
}));
}
#[test]
fn object_aliases() {
assert_snapshot!(generate(TypeScriptOptions {
object_format: ObjectFormat::Type,
..TypeScriptOptions::default()
}));
}
#[test]
fn exclude_refs() {
assert_snapshot!(generate(TypeScriptOptions {
exclude_references: vec!["BasicEnum".into(), "AnotherType".into()],
..TypeScriptOptions::default()
}));
}
#[test]
fn external_types() {
assert_snapshot!(generate(TypeScriptOptions {
external_types: HashMap::from_iter([(
"./externals".into(),
vec!["BasicEnum".into(), "AnotherType".into()]
)]),
..TypeScriptOptions::default()
}));
}
#[test]
fn no_refs() {
assert_snapshot!(generate(TypeScriptOptions {
disable_references: true,
indent_char: " ".into(),
..TypeScriptOptions::default()
}));
}
}