oas3-gen 0.17.2

A rust type generator for OpenAPI v3.1.x specification.
use std::collections::HashSet;

use crate::generator::{
  ast::{EnumDef, FieldDef, RustPrimitive, RustType, StructDef, StructKind, TypeRef, VariantContent, VariantDef},
  codegen::error_impls,
};

#[test]
fn test_generate_error_struct_impl_with_error_field() {
  let struct_def = StructDef {
    name: "MyError".to_string(),
    docs: vec![],
    fields: vec![FieldDef {
      name: "error".to_string(),
      rust_type: TypeRef::new(RustPrimitive::Custom("InnerError".to_string())),
      ..Default::default()
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    methods: vec![],
    kind: StructKind::Schema,
  };

  let result = error_impls::generate_error_impl(&RustType::Struct(struct_def));
  assert!(result.is_some());

  let code = result.unwrap().to_string();
  assert!(code.contains("impl std :: fmt :: Display for MyError"));
  assert!(code.contains("impl std :: error :: Error for MyError"));
  assert!(code.contains("self . error"));
}

#[test]
fn test_generate_error_struct_impl_with_message_field() {
  let struct_def = StructDef {
    name: "MyError".to_string(),
    docs: vec![],
    fields: vec![FieldDef {
      name: "message".to_string(),
      rust_type: TypeRef::new(RustPrimitive::String),
      ..Default::default()
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    methods: vec![],
    kind: StructKind::Schema,
  };

  let result = error_impls::generate_error_impl(&RustType::Struct(struct_def));
  assert!(result.is_some());

  let code = result.unwrap().to_string();
  assert!(code.contains("impl std :: fmt :: Display for MyError"));
  assert!(code.contains("impl std :: error :: Error for MyError"));
  assert!(code.contains("self . message"));
}

#[test]
fn test_generate_error_struct_impl_without_error_fields() {
  let struct_def = StructDef {
    name: "MyError".to_string(),
    docs: vec![],
    fields: vec![FieldDef {
      name: "code".to_string(),
      rust_type: TypeRef::new(RustPrimitive::I32),
      ..Default::default()
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    methods: vec![],
    kind: StructKind::Schema,
  };

  let result = error_impls::generate_error_impl(&RustType::Struct(struct_def));
  assert!(result.is_none());
}

#[test]
fn test_generate_error_enum_impl_with_tuple_variants() {
  let enum_def = EnumDef {
    name: "MyError".to_string(),
    docs: vec![],
    variants: vec![VariantDef {
      name: "BadRequest".to_string(),
      docs: vec![],
      content: VariantContent::Tuple(vec![TypeRef::new(RustPrimitive::String)]),
      serde_attrs: vec![],
      deprecated: false,
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    discriminator: None,
  };

  let result = error_impls::generate_error_impl(&RustType::Enum(enum_def));
  assert!(result.is_some());

  let code = result.unwrap().to_string();
  assert!(code.contains("impl std :: fmt :: Display for MyError"));
  assert!(code.contains("impl std :: error :: Error for MyError"));
  assert!(code.contains("Self :: BadRequest (err)"));
}

#[test]
fn test_generate_error_enum_impl_with_unit_variants() {
  let enum_def = EnumDef {
    name: "MyError".to_string(),
    docs: vec![],
    variants: vec![VariantDef {
      name: "NotFound".to_string(),
      docs: vec![],
      content: VariantContent::Unit,
      serde_attrs: vec![],
      deprecated: false,
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    discriminator: None,
  };

  let result = error_impls::generate_error_impl(&RustType::Enum(enum_def));
  assert!(result.is_none());
}

#[test]
fn test_try_generate_error_impl_for_error_struct() {
  let struct_def = StructDef {
    name: "ApiError".to_string(),
    docs: vec![],
    fields: vec![FieldDef {
      name: "message".to_string(),
      rust_type: TypeRef::new(RustPrimitive::String),
      ..Default::default()
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    methods: vec![],
    kind: StructKind::Schema,
  };

  let rust_type = RustType::Struct(struct_def);
  let mut error_schemas = HashSet::new();
  error_schemas.insert("ApiError".to_string());

  let result = error_impls::generate_error_impl(&rust_type);
  assert!(result.is_some());
}

#[test]
fn test_try_generate_error_impl_for_error_enum() {
  let enum_def = EnumDef {
    name: "ApiError".to_string(),
    docs: vec![],
    variants: vec![VariantDef {
      name: "Error".to_string(),
      docs: vec![],
      content: VariantContent::Tuple(vec![TypeRef::new(RustPrimitive::String)]),
      serde_attrs: vec![],
      deprecated: false,
    }],
    derives: vec![],
    serde_attrs: vec![],
    outer_attrs: vec![],
    discriminator: None,
  };

  let rust_type = RustType::Enum(enum_def);
  let mut error_schemas = HashSet::new();
  error_schemas.insert("ApiError".to_string());

  let result = error_impls::generate_error_impl(&rust_type);
  assert!(result.is_some());
}