-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve
test_integration
internal organization.
- Loading branch information
1 parent
81e03d6
commit 5d4c244
Showing
8 changed files
with
334 additions
and
271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
[[codegen]] | ||
[[test]] | ||
name = "Sync" | ||
base_path = "benches/execution/cornucopia_benches" | ||
destination = "generated_sync.rs" | ||
sync = true | ||
|
||
[[codegen]] | ||
[[test]] | ||
name = "Async" | ||
base_path = "benches/execution/cornucopia_benches" | ||
destination = "generated_async.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,15 @@ | ||
[[codegen]] | ||
[[test]] | ||
name = "Auto build" | ||
base_path = "examples/auto_build" | ||
run = true | ||
|
||
[[codegen]] | ||
[[test]] | ||
name = "Basic sync" | ||
base_path = "examples/basic_sync" | ||
sync = true | ||
run = true | ||
|
||
[[codegen]] | ||
[[test]] | ||
name = "Basic async" | ||
base_path = "examples/basic_async" | ||
run = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
use crate::{ | ||
fixtures::{CodegenTest, TestSuite}, | ||
utils::{reset_db, rustfmt_file, rustfmt_string}, | ||
}; | ||
|
||
use cornucopia::{CodegenSettings, Error}; | ||
use owo_colors::OwoColorize; | ||
use std::{env::set_current_dir, process::Command}; | ||
|
||
// Run codegen test, return true if all test are successful | ||
pub(crate) fn run_codegen_test( | ||
client: &mut postgres::Client, | ||
apply: bool, | ||
) -> Result<bool, Box<dyn std::error::Error>> { | ||
let mut successful = true; | ||
let original_pwd = std::env::current_dir()?; | ||
let fixture_path = "fixtures/codegen"; | ||
|
||
let test_suites = TestSuite::<CodegenTest>::read(fixture_path); | ||
for suite in test_suites { | ||
println!("{}", format!("[codegen] {}", suite.name).magenta()); | ||
for test in suite.tests { | ||
set_current_dir(format!("../{}", test.base_path))?; | ||
|
||
// Load schema | ||
reset_db(client)?; | ||
cornucopia::load_schema(client, vec!["schema.sql".to_string()])?; | ||
|
||
// If `--apply`, then the code will be regenerated. | ||
// Otherwise, it is only checked. | ||
if apply { | ||
// Generate | ||
cornucopia::generate_live( | ||
client, | ||
test.queries_path.to_str().unwrap(), // TODO: Update this once our API accepts paths | ||
Some(test.destination.to_str().unwrap()), // TODO: Update this once our API accepts paths | ||
CodegenSettings::from(&test), | ||
) | ||
.map_err(Error::report)?; | ||
// Format the generated file | ||
rustfmt_file(&test.destination); | ||
} else { | ||
// Get currently checked-in generate file | ||
let old_codegen = std::fs::read_to_string(&test.destination).unwrap(); | ||
// Generate new file | ||
let new_codegen = cornucopia::generate_live( | ||
client, | ||
test.queries_path.to_str().unwrap(), // TODO: Update this once our API accepts paths | ||
None, | ||
CodegenSettings::from(&test), | ||
) | ||
.map_err(Error::report)?; | ||
// Format the generated code string by piping to rustfmt | ||
let new_codegen_formatted = rustfmt_string(&new_codegen); | ||
|
||
// If the newly generated file differs from | ||
// the currently checked in one, return an error. | ||
if old_codegen != new_codegen_formatted { | ||
Err(format!( | ||
"\"{}\" is outdated", | ||
test.destination.to_str().unwrap() | ||
))?; | ||
} | ||
} | ||
println!("(generate) {} {}", test.name, "OK".green()); | ||
|
||
if test.run { | ||
// Change current directory | ||
std::env::set_current_dir(&original_pwd)?; | ||
std::env::set_current_dir(&format!("../{}", test.base_path))?; | ||
// Run | ||
let result = Command::new("cargo").arg("run").output()?; | ||
if result.status.success() { | ||
println!("(run) {} {}", test.name, "OK".green()); | ||
} else { | ||
successful = false; | ||
println!( | ||
" {}\n{}", | ||
"ERR".red(), | ||
String::from_utf8_lossy(&result.stderr) | ||
.as_ref() | ||
.bright_black() | ||
); | ||
} | ||
} | ||
|
||
// Move back to original directory | ||
std::env::set_current_dir(&original_pwd)?; | ||
} | ||
} | ||
|
||
Ok(successful) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use cornucopia::{CodegenSettings, Error}; | ||
use owo_colors::OwoColorize; | ||
|
||
use crate::{ | ||
fixtures::{ErrorTest, TestSuite}, | ||
utils::reset_db, | ||
}; | ||
|
||
/// Run errors test, return true if all test are successful | ||
pub(crate) fn run_errors_test( | ||
client: &mut postgres::Client, | ||
apply: bool, | ||
) -> Result<bool, Box<dyn std::error::Error>> { | ||
let mut successful = true; | ||
let original_pwd = std::env::current_dir().unwrap(); | ||
let test_suites = TestSuite::<ErrorTest>::read("fixtures/errors"); | ||
|
||
for mut suite in test_suites { | ||
println!("{} {}", "[error]".magenta(), suite.name.magenta()); | ||
for test in suite.tests.iter_mut() { | ||
// Generate file tree path | ||
let temp_dir = tempfile::tempdir()?; | ||
|
||
// We need to change current dir for error path to always be the same | ||
std::env::set_current_dir(&temp_dir)?; | ||
|
||
// Generate schema | ||
std::fs::write( | ||
"schema.sql", | ||
[ | ||
"CREATE TABLE author (id SERIAL, name TEXT);\n", | ||
&test.schema, | ||
] | ||
.concat(), | ||
)?; | ||
|
||
// Generate queries files | ||
std::fs::create_dir("queries")?; | ||
std::fs::write("queries/test.sql", &test.query)?; | ||
|
||
// Reset db | ||
reset_db(client)?; | ||
|
||
// Run codegen | ||
let result = cornucopia::load_schema(client, vec!["schema.sql".into()]) | ||
.map_err(Error::from) | ||
.and_then(|_| { | ||
cornucopia::generate_live( | ||
client, | ||
"queries", | ||
None, | ||
CodegenSettings::from(&*test), | ||
) | ||
}); | ||
|
||
let err = result.unwrap_err().report(); | ||
let err_trimmed = err.trim(); | ||
if err_trimmed == test.error.trim() { | ||
println!("{} {}", test.name, "OK".green()); | ||
} else { | ||
let got_msg = if apply { | ||
"Apply:".bright_black() | ||
} else { | ||
"Got:".bright_black() | ||
}; | ||
let expected_msg = if apply { | ||
"Previous:".bright_black() | ||
} else { | ||
"Expected:".bright_black() | ||
}; | ||
successful = false; | ||
println!( | ||
"{} {}\n{}\n{}\n{}\n{}\n", | ||
test.name, | ||
"ERR".red(), | ||
expected_msg, | ||
test.error, | ||
got_msg, | ||
err, | ||
); | ||
} | ||
if apply { | ||
test.error = err_trimmed.into(); | ||
} | ||
std::env::set_current_dir(&original_pwd)?; | ||
} | ||
|
||
if apply { | ||
// Format test descriptor and update error message if needed | ||
let edited = toml::to_string_pretty(&suite.tests)?; | ||
std::fs::write(suite.path, edited)?; | ||
} | ||
} | ||
|
||
Ok(successful) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
use std::path::{Path, PathBuf}; | ||
|
||
use cornucopia::CodegenSettings; | ||
use serde::{de::DeserializeOwned, Deserialize}; | ||
|
||
#[derive(Deserialize)] | ||
struct TestSuiteDeserializer<T> { | ||
test: Vec<T>, | ||
} | ||
|
||
pub struct TestSuite<T> { | ||
pub(crate) name: String, | ||
pub(crate) path: PathBuf, | ||
pub(crate) tests: Vec<T>, | ||
} | ||
|
||
impl<T: DeserializeOwned> TestSuite<T> { | ||
pub(crate) fn read<P: AsRef<Path>>(fixtures_path: P) -> impl Iterator<Item = TestSuite<T>> { | ||
std::fs::read_dir(fixtures_path).unwrap().map(|file| { | ||
let file = file.unwrap(); | ||
let name = file.file_name().to_string_lossy().to_string(); | ||
let path = file.path(); | ||
let content = std::fs::read_to_string(&path).unwrap(); | ||
let tests: TestSuiteDeserializer<T> = toml::from_str(&content).unwrap(); | ||
TestSuite { | ||
name, | ||
tests: tests.test, | ||
path, | ||
} | ||
}) | ||
} | ||
} | ||
|
||
/// Codegen test case | ||
#[derive(Debug, serde::Deserialize)] | ||
pub(crate) struct CodegenTest { | ||
pub(crate) name: String, | ||
pub(crate) base_path: String, | ||
#[serde(default = "default_queries_path")] | ||
pub(crate) queries_path: PathBuf, | ||
#[serde(default = "default_destination_path")] | ||
pub(crate) destination: PathBuf, | ||
#[serde(default)] | ||
pub(crate) sync: bool, | ||
#[serde(default)] | ||
pub(crate) derive_ser: bool, | ||
#[serde(default)] | ||
pub(crate) run: bool, | ||
} | ||
|
||
fn default_queries_path() -> PathBuf { | ||
PathBuf::from("queries") | ||
} | ||
|
||
fn default_destination_path() -> PathBuf { | ||
PathBuf::from("src/cornucopia.rs") | ||
} | ||
|
||
impl From<&CodegenTest> for CodegenSettings { | ||
fn from(codegen_test: &CodegenTest) -> Self { | ||
Self { | ||
is_async: !codegen_test.sync, | ||
derive_ser: codegen_test.derive_ser, | ||
} | ||
} | ||
} | ||
|
||
/// Error test case | ||
#[derive(Debug, serde::Deserialize, serde::Serialize)] | ||
pub(crate) struct ErrorTest { | ||
pub(crate) name: String, | ||
#[serde(default)] | ||
pub(crate) query: String, | ||
#[serde(default)] | ||
pub(crate) schema: String, | ||
pub(crate) error: String, | ||
} | ||
|
||
impl From<&ErrorTest> for CodegenSettings { | ||
fn from(_error_test: &ErrorTest) -> Self { | ||
Self { | ||
is_async: false, | ||
derive_ser: false, | ||
} | ||
} | ||
} |
Oops, something went wrong.