Merge pull request #901 from djc/test-codegen
parser: move code generation into a test
This commit is contained in:
commit
c94465d0f8
|
@ -14,6 +14,9 @@ categories = ["network-programming", "asynchronous"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-graphql-value = { path = "../value", version = "3.0.38" }
|
async-graphql-value = { path = "../value", version = "3.0.38" }
|
||||||
pest = "2.1.3"
|
pest = "2.1.3"
|
||||||
pest_derive = "2.1.0"
|
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
serde = { version = "1.0.125", features = ["derive"] }
|
serde = { version = "1.0.125", features = ["derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
pest_generator = "2.1.3"
|
||||||
|
proc-macro2 = "1.0.37"
|
||||||
|
|
2136
parser/src/parse/generated.rs
Normal file
2136
parser/src/parse/generated.rs
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -2,8 +2,6 @@
|
||||||
//!
|
//!
|
||||||
//! This module's structure mirrors `types`.
|
//! This module's structure mirrors `types`.
|
||||||
|
|
||||||
use std::collections::hash_map::{self, HashMap};
|
|
||||||
|
|
||||||
use pest::{
|
use pest::{
|
||||||
iterators::{Pair, Pairs},
|
iterators::{Pair, Pairs},
|
||||||
Parser,
|
Parser,
|
||||||
|
@ -18,15 +16,15 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
mod executable;
|
mod executable;
|
||||||
|
mod generated;
|
||||||
mod service;
|
mod service;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use async_graphql_value::{ConstValue, Name, Number, Value};
|
use async_graphql_value::{ConstValue, Name, Number, Value};
|
||||||
pub use executable::parse_query;
|
pub use executable::parse_query;
|
||||||
|
use generated::Rule;
|
||||||
pub use service::parse_schema;
|
pub use service::parse_schema;
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[grammar = "graphql.pest"]
|
|
||||||
struct GraphQLParser;
|
struct GraphQLParser;
|
||||||
|
|
||||||
fn parse_operation_type(
|
fn parse_operation_type(
|
||||||
|
|
71
parser/tests/codegen.rs
Normal file
71
parser/tests/codegen.rs
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
//! `pest_derive` crate has large dependency tree, and, as a build dependency,
|
||||||
|
//! it imposes these deps onto our consumers.
|
||||||
|
//!
|
||||||
|
//! To avoid that, let's just dump generated code to string into this
|
||||||
|
//! repository, and add a test that checks that the code is fresh.
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
io::Write,
|
||||||
|
process::{Command, Stdio},
|
||||||
|
};
|
||||||
|
|
||||||
|
const PREAMBLE: &str = "\
|
||||||
|
//! This is @generated code, do not edit by hand.
|
||||||
|
//! See `graphql.pest` and `tests/codegen.rs`.
|
||||||
|
#![allow(unused_attributes)]
|
||||||
|
use super::GraphQLParser;
|
||||||
|
";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generated_code_is_fresh() {
|
||||||
|
let input = format!(
|
||||||
|
r###"
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[grammar = r#"graphql.pest"#]
|
||||||
|
struct GraphQLParser;
|
||||||
|
"###,
|
||||||
|
)
|
||||||
|
.parse::<proc_macro2::TokenStream>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let tokens = pest_generator::derive_parser(input.into(), true);
|
||||||
|
let current =
|
||||||
|
String::from_utf8(fs::read("./src/parse/generated.rs").unwrap_or_default()).unwrap();
|
||||||
|
|
||||||
|
let normalized = normalize(match current.len() > PREAMBLE.len() {
|
||||||
|
true => ¤t[PREAMBLE.len()..],
|
||||||
|
false => current.as_str(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let new = tokens.to_string();
|
||||||
|
let is_up_to_date = normalized == normalize(&new);
|
||||||
|
if is_up_to_date {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let code = format!("{}\n{}", PREAMBLE, reformat(&new));
|
||||||
|
fs::write("./src/parse/generated.rs", code).unwrap();
|
||||||
|
panic!("Generated code in the repository is outdated, updating...");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reformat(code: &str) -> String {
|
||||||
|
let mut cmd = Command::new("rustfmt")
|
||||||
|
.args(&["--config", "tab_spaces=2"])
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
cmd.stdin
|
||||||
|
.take()
|
||||||
|
.unwrap()
|
||||||
|
.write_all(code.as_bytes())
|
||||||
|
.unwrap();
|
||||||
|
let output = cmd.wait_with_output().unwrap();
|
||||||
|
assert!(output.status.success());
|
||||||
|
String::from_utf8(output.stdout).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize(code: &str) -> String {
|
||||||
|
code.replace(|c: char| c.is_ascii_whitespace() || "{},".contains(c), "")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user