Skip to content

chore: add snapshot testing via md files #1054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 55 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
8062aa5
feat(tests/execution_spec): add http support
mogery Jan 27, 2024
33547ce
feat(tests/execution_spec): add snapshot testing
mogery Jan 27, 2024
1fb4e15
feat(testconv): poc for converting http tests
mogery Jan 27, 2024
444d024
feat(testconv): compatibility fixes
mogery Jan 27, 2024
4c13b17
feat(testconv): convert http_spec
mogery Jan 27, 2024
0fd552c
chore: lint
mogery Jan 27, 2024
8d26197
fix(execution_spec): catch up to API changes
mogery Jan 28, 2024
1975923
fix(testconv): order headers correctly for the snapshots
mogery Jan 28, 2024
4e3b4b7
feat(execution_spec): annotation support (without fail)
mogery Jan 28, 2024
77d592c
feat(testconv): support annotations, and deal with fail
mogery Jan 28, 2024
55edaad
feat(execution_spec): allow running only one test explicitly
mogery Jan 28, 2024
304a7b0
feat(testconv): automatically convert fail annotated tests
mogery Jan 28, 2024
bccb5fa
feat(testconv): handle autoconversion of bad graphql
mogery Jan 28, 2024
c8857f7
feat(testconv): auto-run prettier on generated markdown
mogery Jan 28, 2024
45ab945
feat(execution_spec): add server config identity and round-trip checks
mogery Jan 28, 2024
14b6694
feat(testconv): skip tests that use @cache until #1058 is merged
mogery Jan 28, 2024
f95f139
fix(execution_spec): keep up with the API
mogery Jan 30, 2024
efad630
feat(testconv): remove check for #1058
mogery Jan 30, 2024
b7b4783
fix(execution_spec): echo relative paths only for snapshot
mogery Jan 30, 2024
dfed7ac
Merge branch 'main' into mog/execution-spec
mogery Jan 30, 2024
8f9dc00
feat(execution_spec): support graphql merge specs
mogery Jan 30, 2024
ee0bd0d
feat(testconv): convert graphql merge specs
mogery Jan 30, 2024
c0a589d
chore: lint
mogery Jan 30, 2024
311dfc2
Merge branch 'main' into mog/execution-spec
mogery Jan 31, 2024
efd98c3
feat(execution_spec): autocheck client spec for asserts
mogery Jan 31, 2024
f4f3d51
feat(testconv): autogen client spec snapshots for asserts
mogery Jan 31, 2024
a824df3
feat(execution_spec): run client sdl check for every spec with only 1…
mogery Jan 31, 2024
2b291cf
feat(execution_spec): only check merge specs if two or more server bl…
mogery Jan 31, 2024
5489c0d
chore: lint
mogery Jan 31, 2024
b864d3c
feat(testconv): convert client graphql_spec (tests/graphql/*) to exec…
mogery Jan 31, 2024
2aa7477
feat(execution_spec): support snapshotting sdl errors
mogery Jan 31, 2024
5d8e74b
feat(testconv): convert graphql_spec errors to execution_spec
mogery Jan 31, 2024
d9d8361
Merge branch 'main' into mog/execution-spec
mogery Jan 31, 2024
188958d
feat(testconv, execution_spec): keep up with API changes
mogery Jan 31, 2024
b4247e0
chore: lint
mogery Jan 31, 2024
f16187a
fix(execution_spec): resolve configs when error checking
mogery Jan 31, 2024
f1a8d02
feat(execution_spec): support query blocks
mogery Jan 31, 2024
edf6aa1
feat(testconv): convert client-query to execution_spec
mogery Jan 31, 2024
e0d19f9
fix(execution_spec): fix merged expression_name
mogery Jan 31, 2024
c7eda50
feat(execution_spec): add docs
mogery Jan 31, 2024
1e4d198
chore: lint
mogery Jan 31, 2024
db8a1fa
Merge branch 'main' into mog/execution-spec
tusharmath Feb 1, 2024
1019409
fix(execution_spec): adapt to TargetRuntime
mogery Feb 1, 2024
8a5a08b
fix(testconv): keep up with the API
mogery Feb 1, 2024
c83ec79
feat(execution_spec): remove round-trip tests
mogery Feb 1, 2024
191eb6e
feat(execution_spec): use pretty diffing for identity check
mogery Feb 1, 2024
75870ee
feat(testconv): add missing "check identity" instruction to converted…
mogery Feb 1, 2024
20977af
feat(execution_spec, testconv): remove query support
mogery Feb 1, 2024
3281a31
feat(execution_spec, testconv): run merge on every test
mogery Feb 1, 2024
b6f2d40
feat(execution_spec, testconv): seperate assert, mock and env blocks
mogery Feb 1, 2024
50c290c
Merge branch 'main' into mog/execution-spec
mogery Feb 2, 2024
2fcbb37
Merge branch 'main' into mog/execution-spec
mogery Feb 2, 2024
82f35b9
Merge branch 'main' into mog/execution-spec
tusharmath Feb 3, 2024
f4884ce
chore: testconv
mogery Feb 3, 2024
9976d54
chore: document and auto-run testconv
mogery Feb 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ cloudflare/node_modules
cloudflare/pkg

.wrangler/

/tests/snapshots/*.new
9 changes: 8 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
{
"files": [
"add-field-many-list.graphql",
"add-field-many-list.md",
"add-field-many.graphql",
"add-field-many.md",
"inline-many.graphql",
"inline-many.md",
"inline-many-list.graphql",
"inline-many-list.md",
"test-grpc.graphql",
"test-grpc.md",
"test-expr-success.graphql",
"omit-many.graphql"
"test-expr-success.md",
"omit-many.graphql",
"omit-many.md"
],
"options": {
"printWidth": 200
Expand Down
74 changes: 74 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ criterion = "0.5.1"
httpmock = "0.7.0"
pretty_assertions = "1.4.0"
stripmargin = "0.1.1"
markdown = "1.0.0-alpha.16"
insta = { version = "1.34.0", features = ["json"] }

[features]

Expand Down Expand Up @@ -118,7 +120,12 @@ default = ["cli", "js"]


[workspace]
members = [".", "autogen", "cloudflare"]
members = [".", "autogen", "cloudflare", "testconv"]

# Boost execution_spec snapshot diffing performance
[profile.dev.package]
insta.opt-level = 3
similar.opt-level = 3

[profile.release]
opt-level = 3
Expand All @@ -129,6 +136,10 @@ debug = false
incremental = false
overflow-checks = false

[[test]]
name = "execution_spec"
harness = false

[[bench]]
name = "json_like_bench"
harness = false
Expand Down
11 changes: 10 additions & 1 deletion lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ run_autogen_schema() {
return $?
}

run_testconv() {
MODE=$1
if [ "$MODE" == "fix" ]; then
cargo run -p testconv
fi
}

# Extract the mode from the argument
if [[ $1 == "--mode="* ]]; then
MODE=${1#--mode=}
Expand All @@ -57,6 +64,8 @@ case $MODE in
FMT_EXIT_CODE=$?
run_cargo_clippy $MODE
CLIPPY_EXIT_CODE=$?
run_testconv $MODE
TESTCONV_EXIT_CODE=$?
run_prettier $MODE
PRETTIER_EXIT_CODE=$?
;;
Expand All @@ -67,6 +76,6 @@ case $MODE in
esac

# If any command failed, exit with a non-zero status code
if [ $FMT_EXIT_CODE -ne 0 ] || [ $CLIPPY_EXIT_CODE -ne 0 ] || [ $PRETTIER_EXIT_CODE -ne 0 ] || [ $AUTOGEN_SCHEMA_EXIT_CODE -ne 0 ]; then
if [ $FMT_EXIT_CODE -ne 0 ] || [ $CLIPPY_EXIT_CODE -ne 0 ] || [ $PRETTIER_EXIT_CODE -ne 0 ] || [ $AUTOGEN_SCHEMA_EXIT_CODE -ne 0 ] || [ $TESTCONV_EXIT_CODE -ne 0 ]; then
exit 1
fi
18 changes: 18 additions & 0 deletions testconv/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "testconv"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
derive_setters = "0.1.6"
indexmap = { version = "2", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"
tailcall = { path = ".." }
url = { version = "2", features = ["serde"] }
tokio = { version = "1.35.1", features = ["rt", "macros"] }
async-graphql = { version = "7.0.1", features = ["dynamic-schema"] }
regex = "1.10.3"
89 changes: 89 additions & 0 deletions testconv/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use std::collections::BTreeMap;

use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use tailcall::http::Method;
use tailcall::valid::Cause;
use url::Url;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum Annotation {
Skip,
Only,
Fail,
}

#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct APIRequest {
#[serde(default)]
pub method: Method,
pub url: Url,
#[serde(default)]
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub headers: BTreeMap<String, String>,
#[serde(default)]
pub body: serde_json::Value,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct APIResponse {
#[serde(default = "default_status")]
pub status: u16,
#[serde(default)]
#[serde(skip_serializing_if = "IndexMap::is_empty")]
pub headers: IndexMap<String, String>,
#[serde(default)]
pub body: serde_json::Value,
}

fn default_status() -> u16 {
200
}

#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct UpstreamRequest(pub APIRequest);

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UpstreamResponse(pub APIResponse);

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct DownstreamRequest(pub APIRequest);

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct DownstreamResponse(pub APIResponse);

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Mock {
pub request: UpstreamRequest,
pub response: UpstreamResponse,
}

#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
pub struct SDLError {
pub message: String,
pub trace: Vec<String>,
pub description: Option<String>,
}

impl<'a> From<Cause<&'a str>> for SDLError {
fn from(value: Cause<&'a str>) -> Self {
SDLError {
message: value.message.to_string(),
trace: value.trace.iter().map(|e| e.to_string()).collect(),
description: None,
}
}
}

impl From<Cause<String>> for SDLError {
fn from(value: Cause<String>) -> Self {
SDLError {
message: value.message.to_string(),
trace: value.trace.iter().map(|e| e.to_string()).collect(),
description: value.description,
}
}
}
41 changes: 41 additions & 0 deletions testconv/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::collections::HashMap;

use derive_setters::Setters;
use serde::{Deserialize, Serialize};
use tailcall::config::Config;

use crate::common::{Annotation, DownstreamRequest, DownstreamResponse, Mock, UpstreamRequest};

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct DownstreamAssertion {
pub request: DownstreamRequest,
pub response: DownstreamResponse,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub enum ConfigSource {
File(String),
Inline(Config),
}

#[derive(Serialize, Deserialize, Clone, Setters, Debug)]
#[serde(rename_all = "camelCase")]
pub struct HttpSpec {
pub config: ConfigSource,
pub name: String,
pub description: Option<String>,

#[serde(default)]
pub mock: Vec<Mock>,

#[serde(default)]
pub env: HashMap<String, String>,

#[serde(default)]
pub expected_upstream_requests: Vec<UpstreamRequest>,
pub assert: Vec<DownstreamAssertion>,

// Annotations for the runner
pub runner: Option<Annotation>,
}
Loading