actually make import samples run (#2398)

* actually make import samples run

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* format

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2024-05-19 17:02:25 -07:00
committed by GitHub
parent acd52ab350
commit 20838bf618
16 changed files with 412 additions and 386 deletions

View File

@ -201,7 +201,7 @@ fn do_stdlib_inner(
.code_blocks
.iter()
.enumerate()
.map(|(index, code_block)| generate_code_block_test(&fn_name_str, code_block, index, &metadata.tags))
.map(|(index, code_block)| generate_code_block_test(&fn_name_str, code_block, index))
.collect::<Vec<_>>();
let tags = metadata
@ -731,27 +731,13 @@ fn parse_array_type(type_name: &str) -> Option<(&str, usize)> {
// For each kcl code block, we want to generate a test that checks that the
// code block is valid kcl code and compiles and executes.
fn generate_code_block_test(
fn_name: &str,
code_block: &str,
index: usize,
tags: &[String],
) -> proc_macro2::TokenStream {
fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> proc_macro2::TokenStream {
let test_name = format_ident!("serial_test_example_{}{}", fn_name, index);
let test_name_mock = format_ident!("test_mock_example_{}{}", fn_name, index);
let test_name_str = format!("serial_test_example_{}{}", fn_name, index);
// TODO: We ignore import for now, because the files don't exist and we just want
// to show easy imports.
let ignored = if tags.contains(&"norun".to_string()) {
quote! { #[ignore] }
} else {
quote! {}
};
quote! {
#[tokio::test(flavor = "multi_thread")]
#ignored
async fn #test_name_mock() {
let tokens = crate::token::lexer(#code_block).unwrap();
let parser = crate::parser::Parser::new(tokens);
@ -768,7 +754,6 @@ fn generate_code_block_test(
}
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
#ignored
async fn #test_name() {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder()

View File

@ -340,43 +340,6 @@ fn test_stdlib_doc_comment_with_code() {
expectorate::assert_contents("tests/doc_comment_with_code.gen", &get_text_fmt(&item).unwrap());
}
#[test]
fn test_stdlib_doc_comment_with_code_on_ignored_function() {
let (item, errors) = do_stdlib(
quote! {
name = "import",
tags = ["norun"]
},
quote! {
/// This is some function.
/// It does shit.
///
/// This is code.
/// It does other shit.
/// import
///
/// ```
/// This is another code block.
/// yes sirrr.
/// import
/// ```
fn inner_import(
/// The args to do shit to.
args: Option<kittycad::types::InputFormat>
) -> Result<Vec<Box<SketchGroup>>> {
args
}
},
)
.unwrap();
assert!(errors.is_empty());
expectorate::assert_contents(
"tests/doc_comment_with_code_on_ignored_function.gen",
&get_text_fmt(&item).unwrap(),
);
}
#[test]
fn test_stdlib_fail_non_camel_case() {
let (_, errors) = do_stdlib(

View File

@ -1,303 +0,0 @@
#[cfg(test)]
mod test_examples_import {
#[tokio::test(flavor = "multi_thread")]
#[ignore]
async fn test_mock_example_import0() {
let tokens =
crate::token::lexer("This is another code block.\nyes sirrr.\nimport").unwrap();
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let ctx = crate::executor::ExecutorContext {
engine: std::sync::Arc::new(Box::new(
crate::engine::conn_mock::EngineConnection::new()
.await
.unwrap(),
)),
fs: std::sync::Arc::new(crate::fs::FileManager::new()),
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
settings: Default::default(),
is_mock: true,
};
ctx.run(program, None).await.unwrap();
}
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
#[ignore]
async fn serial_test_example_import0() {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder()
.user_agent(user_agent)
.timeout(std::time::Duration::from_secs(600))
.connect_timeout(std::time::Duration::from_secs(60));
let ws_client = reqwest::Client::builder()
.user_agent(user_agent)
.timeout(std::time::Duration::from_secs(600))
.connect_timeout(std::time::Duration::from_secs(60))
.connection_verbose(true)
.tcp_keepalive(std::time::Duration::from_secs(600))
.http1_only();
let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
if let Ok(addr) = std::env::var("LOCAL_ENGINE_ADDR") {
client.set_base_url(addr);
}
let tokens =
crate::token::lexer("This is another code block.\nyes sirrr.\nimport").unwrap();
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let ctx = crate::executor::ExecutorContext::new(&client, Default::default())
.await
.unwrap();
ctx.run(program, None).await.unwrap();
ctx.engine
.send_modeling_cmd(
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::ZoomToFit {
object_ids: Default::default(),
padding: 0.1,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import0"),
&actual,
1.0,
);
}
#[tokio::test(flavor = "multi_thread")]
#[ignore]
async fn test_mock_example_import1() {
let tokens = crate::token::lexer("This is code.\nIt does other shit.\nimport").unwrap();
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let ctx = crate::executor::ExecutorContext {
engine: std::sync::Arc::new(Box::new(
crate::engine::conn_mock::EngineConnection::new()
.await
.unwrap(),
)),
fs: std::sync::Arc::new(crate::fs::FileManager::new()),
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
settings: Default::default(),
is_mock: true,
};
ctx.run(program, None).await.unwrap();
}
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
#[ignore]
async fn serial_test_example_import1() {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder()
.user_agent(user_agent)
.timeout(std::time::Duration::from_secs(600))
.connect_timeout(std::time::Duration::from_secs(60));
let ws_client = reqwest::Client::builder()
.user_agent(user_agent)
.timeout(std::time::Duration::from_secs(600))
.connect_timeout(std::time::Duration::from_secs(60))
.connection_verbose(true)
.tcp_keepalive(std::time::Duration::from_secs(600))
.http1_only();
let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
if let Ok(addr) = std::env::var("LOCAL_ENGINE_ADDR") {
client.set_base_url(addr);
}
let tokens = crate::token::lexer("This is code.\nIt does other shit.\nimport").unwrap();
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let ctx = crate::executor::ExecutorContext::new(&client, Default::default())
.await
.unwrap();
ctx.run(program, None).await.unwrap();
ctx.engine
.send_modeling_cmd(
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::ZoomToFit {
object_ids: Default::default(),
padding: 0.1,
},
)
.await
.unwrap();
let resp = ctx
.engine
.send_modeling_cmd(
uuid::Uuid::new_v4(),
crate::executor::SourceRange::default(),
kittycad::types::ModelingCmd::TakeSnapshot {
format: kittycad::types::ImageFormat::Png,
},
)
.await
.unwrap();
let output_file =
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
if let kittycad::types::OkWebSocketResponseData::Modeling {
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
} = &resp
{
std::fs::write(&output_file, &data.contents.0).unwrap();
} else {
panic!("Unexpected response from engine: {:?}", resp);
}
let actual = image::io::Reader::open(output_file)
.unwrap()
.decode()
.unwrap();
twenty_twenty::assert_image(
&format!("tests/outputs/{}.png", "serial_test_example_import1"),
&actual,
1.0,
);
}
}
#[allow(non_camel_case_types, missing_docs)]
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
#[ts(export)]
pub(crate) struct Import {}
#[allow(non_upper_case_globals, missing_docs)]
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
pub(crate) const Import: Import = Import {};
fn boxed_import(
args: crate::std::Args,
) -> std::pin::Pin<
Box<
dyn std::future::Future<
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
> + Send,
>,
> {
Box::pin(import(args))
}
impl crate::docs::StdLibFn for Import {
fn name(&self) -> String {
"import".to_string()
}
fn summary(&self) -> String {
"This is some function.".to_string()
}
fn description(&self) -> String {
"It does shit.".to_string()
}
fn tags(&self) -> Vec<String> {
vec!["norun".to_string()]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "kittycad::types::InputFormat".to_string(),
schema: <Option<kittycad::types::InputFormat>>::json_schema(&mut generator),
required: false,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "[SketchGroup]".to_string(),
schema: <Vec<SketchGroup>>::json_schema(&mut generator),
required: true,
})
}
fn unpublished(&self) -> bool {
false
}
fn deprecated(&self) -> bool {
false
}
fn examples(&self) -> Vec<String> {
let code_blocks = vec![
"This is another code block.\nyes sirrr.\nimport",
"This is code.\nIt does other shit.\nimport",
];
code_blocks
.iter()
.map(|cb| {
let tokens = crate::token::lexer(cb).unwrap();
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let mut options: crate::ast::types::FormatOptions = Default::default();
options.insert_final_newline = false;
program.recast(&options, 0)
})
.collect::<Vec<String>>()
}
fn std_lib_fn(&self) -> crate::std::StdFn {
boxed_import
}
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
Box::new(self.clone())
}
}
#[doc = r" This is some function."]
#[doc = r" It does shit."]
#[doc = r""]
#[doc = r" This is code."]
#[doc = r" It does other shit."]
#[doc = r" import"]
#[doc = r""]
#[doc = r" ```"]
#[doc = r" This is another code block."]
#[doc = r" yes sirrr."]
#[doc = r" import"]
#[doc = r" ```"]
fn inner_import(
#[doc = r" The args to do shit to."] args: Option<kittycad::types::InputFormat>,
) -> Result<Vec<Box<SketchGroup>>> {
args
}