Document test output JSON schema through '--help'
The help manual is getting a bit large, but fortunately, we can resort to a simpler/more compact version using `-h`.
This commit is contained in:
parent
da982510dc
commit
51a8ddcc0b
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- **aiken**: Optionally provide blueprint file location when using `blueprint apply` @Riley-Kilgore
|
- **aiken**: Optionally provide blueprint file location when using `blueprint apply`. @Riley-Kilgore
|
||||||
|
- **aiken**: Output test results as structured JSON when the target output is not a TTY terminal. @Riley-Kilgore, @KtorZ
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
- **aiken-project**: Fix `aiken docs` wrongly formatting list constants as tuples. See [#1048](https://github.com/aiken-lang/aiken/issues/1048). @KtorZ
|
- **aiken-project**: Fix `aiken docs` wrongly formatting list constants as tuples. See [#1048](https://github.com/aiken-lang/aiken/issues/1048). @KtorZ
|
||||||
- **aiken-project**: Fix `aiken docs` source linking crashing when generating docs for config modules. See [#1044](https://github.com/aiken-lang/aiken/issues/1044). @KtorZ
|
- **aiken-project**: Fix `aiken docs` source linking crashing when generating docs for config modules. See [#1044](https://github.com/aiken-lang/aiken/issues/1044). @KtorZ
|
||||||
- **aiken-project**: Fix `aiken docs` generating very long lines for constants. @KtorZ
|
- **aiken-project**: Fix `aiken docs` generating very long lines for constants. @KtorZ
|
||||||
|
- **aiken-lang**: Leverage [Decision Trees](https://www.cs.tufts.edu/comp/150FP/archive/luc-maranget/jun08.pdf) for compiling pattern matches to UPLC. @MicroProofs
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ dependencies = [
|
||||||
"aiken-project",
|
"aiken-project",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
"color-print",
|
||||||
"hex",
|
"hex",
|
||||||
"ignore",
|
"ignore",
|
||||||
"indoc",
|
"indoc",
|
||||||
|
@ -590,6 +591,27 @@ version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "color-print"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3aa954171903797d5623e047d9ab69d91b493657917bdfb8c2c80ecaf9cdb6f4"
|
||||||
|
dependencies = [
|
||||||
|
"color-print-proc-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "color-print-proc-macro"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "692186b5ebe54007e45a59aea47ece9eb4108e141326c304cdc91699a7118a22"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.77",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
|
@ -45,16 +45,27 @@ impl EventListener for Json {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_test_json(result: &TestResult<UntypedExpr, UntypedExpr>) -> serde_json::Value {
|
fn fmt_test_json(result: &TestResult<UntypedExpr, UntypedExpr>) -> serde_json::Value {
|
||||||
|
let on_test_failure = match result {
|
||||||
|
TestResult::UnitTestResult(UnitTestResult { ref test, .. }) => &test.on_test_failure,
|
||||||
|
TestResult::PropertyTestResult(PropertyTestResult { ref test, .. }) => {
|
||||||
|
&test.on_test_failure
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut test = json!({
|
let mut test = json!({
|
||||||
"title": result.title(),
|
"title": result.title(),
|
||||||
"status": if result.is_success() { "pass" } else { "fail" },
|
"status": if result.is_success() { "pass" } else { "fail" },
|
||||||
|
"on_failure": match on_test_failure {
|
||||||
|
OnTestFailure::FailImmediately => "fail_immediately" ,
|
||||||
|
OnTestFailure::SucceedEventually => "succeed_eventually" ,
|
||||||
|
OnTestFailure::SucceedImmediately => "succeed_immediately",
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
TestResult::UnitTestResult(UnitTestResult {
|
TestResult::UnitTestResult(UnitTestResult {
|
||||||
spent_budget,
|
spent_budget,
|
||||||
assertion,
|
assertion,
|
||||||
test: unit_test,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
test["execution_units"] = json!({
|
test["execution_units"] = json!({
|
||||||
|
@ -63,14 +74,8 @@ fn fmt_test_json(result: &TestResult<UntypedExpr, UntypedExpr>) -> serde_json::V
|
||||||
});
|
});
|
||||||
if !result.is_success() {
|
if !result.is_success() {
|
||||||
if let Some(assertion) = assertion {
|
if let Some(assertion) = assertion {
|
||||||
test["assertion"] = json!({
|
test["assertion"] =
|
||||||
"message": assertion.to_string(false, &AssertionStyleOptions::new(None)),
|
json!(assertion.to_string(false, &AssertionStyleOptions::new(None)));
|
||||||
"on_failure": match unit_test.on_test_failure {
|
|
||||||
OnTestFailure::FailImmediately => "fail_immediately" ,
|
|
||||||
OnTestFailure::SucceedEventually => "succeed_eventually" ,
|
|
||||||
OnTestFailure::SucceedImmediately => "succeed_immediately",
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +86,9 @@ fn fmt_test_json(result: &TestResult<UntypedExpr, UntypedExpr>) -> serde_json::V
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
test["iterations"] = json!(iterations);
|
test["iterations"] = json!(iterations);
|
||||||
|
if !labels.is_empty() {
|
||||||
test["labels"] = json!(labels);
|
test["labels"] = json!(labels);
|
||||||
|
}
|
||||||
test["counterexample"] = match counterexample {
|
test["counterexample"] = match counterexample {
|
||||||
Ok(Some(expr)) => json!(Formatter::new().expr(expr, false).to_pretty_string(60)),
|
Ok(Some(expr)) => json!(Formatter::new().expr(expr, false).to_pretty_string(60)),
|
||||||
Ok(None) => json!(null),
|
Ok(None) => json!(null),
|
||||||
|
|
|
@ -30,6 +30,7 @@ clap = { version = "4.1.8", features = [
|
||||||
"string",
|
"string",
|
||||||
] }
|
] }
|
||||||
clap_complete = "4.3.2"
|
clap_complete = "4.3.2"
|
||||||
|
color-print = "0.3.7"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
ignore = "0.4.20"
|
ignore = "0.4.20"
|
||||||
indoc = "2.0"
|
indoc = "2.0"
|
||||||
|
|
|
@ -12,7 +12,101 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(clap::Args)]
|
#[derive(clap::Args)]
|
||||||
/// Type-check an Aiken project
|
#[command(
|
||||||
|
verbatim_doc_comment,
|
||||||
|
about = color_print::cstr!(r#"
|
||||||
|
Type-check an Aiken project and run any tests found.
|
||||||
|
|
||||||
|
Test results are printed as stylized outputs when `stdout` is a TTY-capable terminal. If it
|
||||||
|
isn't, (e.g. because you are redirecting the output to a file), test results are printed as
|
||||||
|
a JSON structured object. Use `--help` to see the whole schema.
|
||||||
|
"#),
|
||||||
|
after_long_help = color_print::cstr!(r#"<bold><underline>Output JSON schema:</underline></bold>
|
||||||
|
<bold>type</bold>: object
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>seed</bold>: <cyan>&type_integer</cyan>
|
||||||
|
<bold>type</bold>: integer
|
||||||
|
<bold>summary</bold>:
|
||||||
|
<bold>type</bold>: object
|
||||||
|
<bold>properties</bold>: <cyan>&type_summary</cyan>
|
||||||
|
<bold>total</bold>: *type_integer
|
||||||
|
<bold>passed</bold>: *type_integer
|
||||||
|
<bold>failed</bold>: *type_integer
|
||||||
|
<bold>kind</bold>:
|
||||||
|
<bold>type</bold>: object
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>unit</bold>: *type_integer
|
||||||
|
<bold>property</bold>: *type_integer
|
||||||
|
<bold>modules</bold>:
|
||||||
|
<bold>type</bold>: array
|
||||||
|
<bold>items</bold>:
|
||||||
|
<bold>type</bold>: object
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>name</bold>: <cyan>&type_string</cyan>
|
||||||
|
<bold>type</bold>: string
|
||||||
|
<bold>summary</bold>: *type_summary
|
||||||
|
<bold>test</bold>:
|
||||||
|
<bold>type</bold>: array
|
||||||
|
<bold>items</bold>:
|
||||||
|
<bold>oneOf</bold>:
|
||||||
|
- <bold>type</bold>: object
|
||||||
|
<bold>required</bold>:
|
||||||
|
- kind
|
||||||
|
- title
|
||||||
|
- status
|
||||||
|
- on_failure
|
||||||
|
- execution_units
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>kind</bold>
|
||||||
|
<bold>type</bold>: string
|
||||||
|
<bold>enum</bold>: [ "unit" ]
|
||||||
|
<bold>title</bold>: *type_string
|
||||||
|
<bold>status</bold>: <cyan>&type_status</cyan>
|
||||||
|
<bold>type</bold>: string
|
||||||
|
<bold>enum</bold>: [ "pass", "fail" ]
|
||||||
|
<bold>on_failure</bold>: <cyan>&type_on_failure</cyan>
|
||||||
|
<bold>type</bold>: string
|
||||||
|
<bold>enum</bold>:
|
||||||
|
- fail_immediately
|
||||||
|
- succeed_immediately
|
||||||
|
- succeed_eventually
|
||||||
|
<bold>execution_units</bold>:
|
||||||
|
<bold>type</bold>: object
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>mem</bold>: *type_integer
|
||||||
|
<bold>cpu</bold>: *type_integer
|
||||||
|
<bold>assertion</bold>: *type_string
|
||||||
|
- <bold>type</bold>: object
|
||||||
|
<bold>required</bold>:
|
||||||
|
- kind
|
||||||
|
- title
|
||||||
|
- status
|
||||||
|
- on_failure
|
||||||
|
- iterations
|
||||||
|
- counterexample
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>kind</bold>
|
||||||
|
<bold>type</bold>: string
|
||||||
|
<bold>enum</bold>: [ "property" ]
|
||||||
|
<bold>title</bold>: *type_string
|
||||||
|
<bold>status</bold>: *type_status
|
||||||
|
<bold>on_failure</bold>: *type_on_failure
|
||||||
|
<bold>iterations</bold>: *type_integer
|
||||||
|
<bold>labels</bold>:
|
||||||
|
<bold>type</bold>: object
|
||||||
|
<bold>additionalProperties</bold>: *type_integer
|
||||||
|
<bold>counterexample</bold>:
|
||||||
|
<bold>oneOf</bold>:
|
||||||
|
- *type_string
|
||||||
|
- <bold>type</bold>: "null"
|
||||||
|
- <bold>type</bold>: object
|
||||||
|
<bold>properties</bold>:
|
||||||
|
<bold>error</bold>: *type_string
|
||||||
|
|
||||||
|
<bold><underline>Note:</underline></bold>
|
||||||
|
You are seeing the extended help. Use `-h` instead of `--help` for a more compact view.
|
||||||
|
"#
|
||||||
|
))]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
/// Path to project
|
/// Path to project
|
||||||
directory: Option<PathBuf>,
|
directory: Option<PathBuf>,
|
||||||
|
@ -44,7 +138,7 @@ pub struct Args {
|
||||||
/// Only run tests if they match any of these strings.
|
/// Only run tests if they match any of these strings.
|
||||||
/// You can match a module with `-m aiken/list` or `-m list`.
|
/// You can match a module with `-m aiken/list` or `-m list`.
|
||||||
/// You can match a test with `-m "aiken/list.{map}"` or `-m "aiken/option.{flatten_1}"`
|
/// You can match a test with `-m "aiken/list.{map}"` or `-m "aiken/option.{flatten_1}"`
|
||||||
#[clap(short, long)]
|
#[clap(short, long, verbatim_doc_comment)]
|
||||||
match_tests: Option<Vec<String>>,
|
match_tests: Option<Vec<String>>,
|
||||||
|
|
||||||
/// This is meant to be used with `--match-tests`.
|
/// This is meant to be used with `--match-tests`.
|
||||||
|
@ -76,14 +170,9 @@ pub struct Args {
|
||||||
|
|
||||||
/// Choose the verbosity level of traces:
|
/// Choose the verbosity level of traces:
|
||||||
///
|
///
|
||||||
/// - silent:
|
/// - silent: disable traces altogether
|
||||||
/// disable traces altogether
|
/// - compact: only culprit line numbers are shown on failures
|
||||||
///
|
/// - verbose: enable full verbose traces as provided by the user or the compiler
|
||||||
/// - compact:
|
|
||||||
/// only culprit line numbers are shown on failures
|
|
||||||
///
|
|
||||||
/// - verbose:
|
|
||||||
/// enable full verbose traces as provided by the user or the compiler
|
|
||||||
///
|
///
|
||||||
/// [optional]
|
/// [optional]
|
||||||
#[clap(short, long, value_parser=trace_level_parser(), default_value_t=TraceLevel::Verbose, verbatim_doc_comment)]
|
#[clap(short, long, value_parser=trace_level_parser(), default_value_t=TraceLevel::Verbose, verbatim_doc_comment)]
|
||||||
|
|
Loading…
Reference in New Issue