Skip to content

Commit 1093860

Browse files
gnd(test): Address PR review comments
- Add -s short flag for --skip-build - Print deprecation warning when --matchstick is used; update README - Replace npm with pnpm in integration test setup - Replace hand-rolled r_value_to_json with serde_json::to_value via r::Value's built-in Serialize impl (also fixes Timestamp serialization) - Make find_asc_binary pub and re-export from compiler module; reuse it in gnd_test.rs instead of duplicating the lookup logic - Skip DB cleanup on test failure for persistent databases and print the connection URL so the data can be inspected
1 parent 521379c commit 1093860

7 files changed

Lines changed: 41 additions & 66 deletions

File tree

gnd/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,9 @@ gnd test [TEST_FILES...]
315315
| Flag | Short | Description |
316316
|------|-------|-------------|
317317
| `--manifest` | `-m` | Path to subgraph manifest (default: `subgraph.yaml`) |
318-
| `--skip-build` | | Skip building the subgraph before testing |
318+
| `--skip-build` | `-s` | Skip building the subgraph before testing |
319319
| `--postgres-url` | | PostgreSQL connection URL (env: `POSTGRES_URL`) |
320-
| `--matchstick` | | Use legacy Matchstick runner |
320+
| `--matchstick` | | Use legacy Matchstick runner (**deprecated** — migrate to JSON-based tests) |
321321
| `--docker` | `-d` | Run Matchstick in Docker (requires `--matchstick`) |
322322
| `--coverage` | `-c` | Run with coverage reporting (requires `--matchstick`) |
323323
| `--recompile` | `-r` | Force recompilation (requires `--matchstick`) |
@@ -340,7 +340,7 @@ gnd test my-tests/
340340
gnd test -m subgraph.staging.yaml tests/transfer.json
341341

342342
# Skip automatic build
343-
gnd test --skip-build
343+
gnd test -s
344344
```
345345

346346
### `gnd clean`

gnd/src/commands/test/assertion.rs

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::runner::TestContext;
44
use super::schema::{Assertion, AssertionFailure, AssertionOutcome, TestResult};
55
use anyhow::{anyhow, Result};
66
use graph::data::query::{Query, QueryResults, QueryTarget};
7-
use graph::prelude::{q, r, ApiVersion, GraphQlRunner as GraphQlRunnerTrait};
7+
use graph::prelude::{q, ApiVersion, GraphQlRunner as GraphQlRunnerTrait};
88

99
pub(super) async fn run_assertions(
1010
ctx: &TestContext,
@@ -62,7 +62,7 @@ async fn run_single_assertion(
6262
.map_err(|errors| anyhow!("Query errors: {:?}", errors))?;
6363

6464
let actual_json = match result {
65-
Some(value) => r_value_to_json(&value),
65+
Some(value) => serde_json::to_value(&value)?,
6666
None => serde_json::Value::Null,
6767
};
6868

@@ -77,32 +77,6 @@ async fn run_single_assertion(
7777
}
7878
}
7979

80-
/// Convert graph-node's internal `r::Value` (GraphQL result) to `serde_json::Value`.
81-
///
82-
/// Graph-node uses its own value type for GraphQL results. This converts to
83-
/// standard JSON for comparison with the expected values in the test file.
84-
fn r_value_to_json(value: &r::Value) -> serde_json::Value {
85-
match value {
86-
r::Value::Null => serde_json::Value::Null,
87-
r::Value::Boolean(b) => serde_json::Value::Bool(*b),
88-
r::Value::Int(n) => serde_json::Value::Number((*n).into()),
89-
r::Value::Float(f) => serde_json::json!(*f),
90-
r::Value::String(s) => serde_json::Value::String(s.clone()),
91-
r::Value::Enum(s) => serde_json::Value::String(s.clone()),
92-
r::Value::List(list) => {
93-
serde_json::Value::Array(list.iter().map(r_value_to_json).collect())
94-
}
95-
r::Value::Object(obj) => {
96-
let map: serde_json::Map<String, serde_json::Value> = obj
97-
.iter()
98-
.map(|(k, v)| (k.to_string(), r_value_to_json(v)))
99-
.collect();
100-
serde_json::Value::Object(map)
101-
}
102-
r::Value::Timestamp(t) => serde_json::Value::String(t.to_string()),
103-
}
104-
}
105-
10680
/// Reorder `actual` arrays to align with `expected`'s element ordering.
10781
///
10882
/// When a test fails, the raw diff can be misleading if array elements appear

gnd/src/commands/test/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ pub struct TestOpt {
5959
pub manifest: PathBuf,
6060

6161
/// Skip building the subgraph before testing
62-
#[clap(long)]
62+
#[clap(short = 's', long)]
6363
pub skip_build: bool,
6464

6565
/// PostgreSQL connection URL. If not provided, a temporary database will be created (Unix only).
6666
#[clap(long, env = "POSTGRES_URL")]
6767
pub postgres_url: Option<String>,
6868

69-
/// Use Matchstick runner instead (legacy mode)
69+
/// Use Matchstick runner instead (deprecated legacy mode — migrate to JSON-based tests)
7070
#[clap(long)]
7171
pub matchstick: bool,
7272

@@ -102,6 +102,11 @@ pub struct TestOpt {
102102

103103
pub async fn run_test(opt: TestOpt) -> Result<()> {
104104
if opt.matchstick {
105+
step(
106+
Step::Warn,
107+
"Matchstick is deprecated and will be removed in a future release. \
108+
Migrate to the JSON-based test format (see: gnd/docs/gnd-test.md).",
109+
);
105110
return matchstick::run(&opt).await;
106111
}
107112

gnd/src/commands/test/runner.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,25 @@ pub async fn run_single_test(
310310
.await;
311311

312312
// For persistent databases, clean up the deployment after the test so the
313-
// database is left in a clean state. Each run generates a unique hash and
314-
// subgraph name (via the seed), so pre-test cleanup is not needed — only
315-
// post-test cleanup of the current run's deployment.
313+
// database is left in a clean state. On failure, skip cleanup so the data
314+
// is preserved for inspection.
316315
if db.needs_cleanup() {
317-
cleanup(
318-
&ctx.store,
319-
&manifest_info.subgraph_name,
320-
&manifest_info.hash,
321-
)
322-
.await
323-
.ok();
316+
let test_passed = result.as_ref().map(|r| r.is_passed()).unwrap_or(false);
317+
if test_passed {
318+
cleanup(
319+
&ctx.store,
320+
&manifest_info.subgraph_name,
321+
&manifest_info.hash,
322+
)
323+
.await
324+
.ok();
325+
} else {
326+
eprintln!(
327+
" {} Test failed — database preserved for inspection: {}",
328+
console::style("ℹ").cyan(),
329+
db.url()
330+
);
331+
}
324332
}
325333

326334
result

gnd/src/compiler/asc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ pub fn find_graph_ts(source_dir: &Path) -> Result<(Vec<PathBuf>, PathBuf)> {
181181

182182
/// Find the `asc` binary by checking the global PATH first, then the project's
183183
/// root `node_modules/.bin/asc`.
184-
fn find_asc_binary(base_dir: &Path) -> Option<PathBuf> {
184+
pub fn find_asc_binary(base_dir: &Path) -> Option<PathBuf> {
185185
// Check global PATH first
186186
if Command::new("asc")
187187
.arg("--version")

gnd/src/compiler/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
66
mod asc;
77

8-
pub use asc::{compile_mapping, find_graph_ts, AscCompileOptions};
8+
pub use asc::{compile_mapping, find_asc_binary, find_graph_ts, AscCompileOptions};

gnd/tests/gnd_test.rs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//!
1515
//! - Build the gnd binary: `cargo build -p gnd`
1616
//! - AssemblyScript compiler (`asc`) in PATH
17-
//! - npm available for dependency installation
17+
//! - pnpm available for dependency installation
1818
//!
1919
//! # Running
2020
//!
@@ -33,7 +33,7 @@ use std::process::Command;
3333
use tempfile::TempDir;
3434
use walkdir::WalkDir;
3535

36-
/// Copy the fixture subgraph into a fresh temp directory, install npm
36+
/// Copy the fixture subgraph into a fresh temp directory, install pnpm
3737
/// dependencies, and run `gnd codegen`. Returns the temp dir handle (to
3838
/// keep it alive) and the path to the prepared subgraph directory.
3939
fn setup_fixture() -> (TempDir, PathBuf) {
@@ -50,16 +50,16 @@ fn setup_fixture() -> (TempDir, PathBuf) {
5050

5151
copy_dir_recursive(&fixture, &subgraph_dir).expect("Failed to copy fixture to temp directory");
5252

53-
// Install npm dependencies (graph-ts, graph-cli)
54-
let npm_output = Command::new("npm")
53+
// Install dependencies (graph-ts, graph-cli)
54+
let npm_output = Command::new("pnpm")
5555
.arg("install")
5656
.current_dir(&subgraph_dir)
5757
.output()
58-
.expect("Failed to run `npm install`. Is npm available?");
58+
.expect("Failed to run `pnpm install`. Is pnpm available?");
5959

6060
assert!(
6161
npm_output.status.success(),
62-
"npm install failed in fixture:\nstdout: {}\nstderr: {}",
62+
"pnpm install failed in fixture:\nstdout: {}\nstderr: {}",
6363
String::from_utf8_lossy(&npm_output.stdout),
6464
String::from_utf8_lossy(&npm_output.stderr),
6565
);
@@ -116,23 +116,11 @@ fn fixture_path() -> PathBuf {
116116

117117
/// Assert that `asc` (AssemblyScript compiler) is available in PATH or in local node_modules.
118118
fn verify_asc_available(subgraph_dir: &Path) {
119-
// Check global PATH first
120-
if Command::new("asc")
121-
.arg("--version")
122-
.output()
123-
.map(|o| o.status.success())
124-
.unwrap_or(false)
125-
{
126-
return;
127-
}
128-
129-
// Fall back to local node_modules/.bin/asc
130-
let local_asc = subgraph_dir.join("node_modules").join(".bin").join("asc");
131119
assert!(
132-
local_asc.exists(),
133-
"asc compiler not found globally or at {}. \
120+
gnd::compiler::find_asc_binary(subgraph_dir).is_some(),
121+
"asc compiler not found globally or in {}/node_modules/.bin. \
134122
Install it with: npm install -g assemblyscript@0.19.23",
135-
local_asc.display()
123+
subgraph_dir.display()
136124
);
137125
}
138126

0 commit comments

Comments
 (0)