use cucumber::World;
use step_defs::{integration, unit};
mod step_defs;
struct Feature {
path: &'static str,
gate: Option<&'static str>,
excluded_tags: &'static [&'static str],
excluded_scenarios: &'static [&'static str],
}
const INTEGRATION_FEATURES: &[Feature] = &[
Feature {
path: "tests/features/integration/applications.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/abi.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/c2c.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/algod.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/compile.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/assets.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/auction.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/dryrun.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/dryrun_testing.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/kmd.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/rekey.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/send.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/integration/simulate.feature",
gate: None,
excluded_tags: &[
"simulate.exec_trace_with_stack_scratch",
"simulate.exec_trace_with_state_change_and_hash",
],
excluded_scenarios: &[],
},
];
const UNIT_FEATURES: &[Feature] = &[
Feature {
path: "tests/features/unit/abijson.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/algodclient_paths.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/atomic_transaction_composer.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/client-no-headers.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/dryrun_trace.feature",
gate: Some("blocked on ADRs dryrun-request-builder and cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/feetest.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/offline.feature",
gate: None,
excluded_tags: &[
"unit.offline.sign",
"unit.offline.signMsig",
"unit.offline.signFlat",
"unit.offline.signFlatLogic",
"unit.offline.appendMsig",
"unit.offline.mergeMsig",
],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/program_sanity_check.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/rekey.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/responses.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/sourcemap.feature",
gate: Some("blocked on ADRs teal-source-map-decoder and cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/tealsign.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/transactions.feature",
gate: Some("blocked on ADR cucumber-unit-test-scaffolding"),
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/v2algodclient_paths.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &["Get Block, header-only"],
},
Feature {
path: "tests/features/unit/v2algodclient_responses.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
Feature {
path: "tests/features/unit/v2indexerclient_paths.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[
"SearchAccounts path with OnlineOnly",
"SearchForTransactions path",
],
},
Feature {
path: "tests/features/unit/v2indexerclient_responses.feature",
gate: None,
excluded_tags: &[],
excluded_scenarios: &[],
},
];
fn scenario_enabled(
sc: &cucumber::gherkin::Scenario,
excluded_tags: &[&str],
excluded_scenarios: &[&str],
) -> bool {
if sc.tags.iter().any(|t| excluded_tags.contains(&t.as_str())) {
return false;
}
for entry in excluded_scenarios {
match entry.split_once("::") {
Some((tag, name)) => {
if sc.name == name && sc.tags.iter().any(|t| t == tag) {
return false;
}
}
None => {
if sc.name == *entry {
return false;
}
}
}
}
true
}
async fn run_integration(
path: &str,
excluded_tags: &'static [&'static str],
excluded_scenarios: &'static [&'static str],
) {
integration::world::World::cucumber()
.max_concurrent_scenarios(1)
.filter_run(path, move |_, _, sc| {
scenario_enabled(sc, excluded_tags, excluded_scenarios)
})
.await;
}
async fn run_unit(
path: &str,
excluded_tags: &'static [&'static str],
excluded_scenarios: &'static [&'static str],
) {
unit::world::UnitWorld::cucumber()
.max_concurrent_scenarios(1)
.filter_run(path, move |_, _, sc| {
scenario_enabled(sc, excluded_tags, excluded_scenarios)
})
.await;
}
#[tokio::main]
async fn main() {
let mut skipped: Vec<(&str, &str)> = Vec::new();
for feature in INTEGRATION_FEATURES {
match feature.gate {
None => {
run_integration(
feature.path,
feature.excluded_tags,
feature.excluded_scenarios,
)
.await
}
Some(reason) => skipped.push((feature.path, reason)),
}
}
for feature in UNIT_FEATURES {
match feature.gate {
None => {
run_unit(
feature.path,
feature.excluded_tags,
feature.excluded_scenarios,
)
.await
}
Some(reason) => skipped.push((feature.path, reason)),
}
}
if !skipped.is_empty() {
eprintln!("\nSkipped features (see docs/adr/ for status):");
for (path, reason) in skipped {
eprintln!(" - {path}\n {reason}");
}
}
}