about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2024-07-19 16:46:03 +0200
committerLeón Orell Valerian Liehr <me@fmease.dev>2024-07-19 16:54:16 +0200
commit25be41cfb8c2fa1c59b8193b68801a75f5603d8f (patch)
tree51bb746b446f8c74ab4b23a9177e184a8ac7128e
parent11e57241f166194a328438d9264b68c98a18d51f (diff)
downloadrust-25be41cfb8c2fa1c59b8193b68801a75f5603d8f.tar.gz
rust-25be41cfb8c2fa1c59b8193b68801a75f5603d8f.zip
Update jsondocck directives to follow ui_test-style
-rwxr-xr-xsrc/etc/htmldocck.py1
-rw-r--r--src/tools/compiletest/src/header.rs31
-rw-r--r--src/tools/jsondocck/src/main.rs67
3 files changed, 52 insertions, 47 deletions
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index 3d7ead99282..599e1e8102c 100755
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -266,6 +266,7 @@ def get_known_directive_names():
 # To prevent duplicating the list of commmands between `compiletest` and `htmldocck`, we put
 # it into a common file which is included in rust code and parsed here.
 # FIXME: This setup is temporary until we figure out how to improve this situation.
+#        See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
 KNOWN_DIRECTIVE_NAMES = get_known_directive_names()
 
 LINE_PATTERN = re.compile(r'''
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 7f5d4f4b416..3afb5e27547 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -723,12 +723,13 @@ pub fn line_directive<'line>(
     }
 }
 
-// To prevent duplicating the list of commmands between `compiletest` and `htmldocck`, we put
-// it into a common file which is included in rust code and parsed here.
+// To prevent duplicating the list of commmands between `compiletest`,`htmldocck` and `jsondocck`,
+// we put it into a common file which is included in rust code and parsed here.
 // FIXME: This setup is temporary until we figure out how to improve this situation.
+//        See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
 include!("command-list.rs");
 
-const KNOWN_RUSTDOC_DIRECTIVE_NAMES: &[&str] = &[
+const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[
     "count",
     "!count",
     "files",
@@ -747,6 +748,9 @@ const KNOWN_RUSTDOC_DIRECTIVE_NAMES: &[&str] = &[
     "!snapshot",
 ];
 
+const KNOWN_JSONDOCCK_DIRECTIVE_NAMES: &[&str] =
+    &["count", "!count", "has", "!has", "is", "!is", "ismany", "!ismany", "set", "!set"];
+
 /// The broken-down contents of a line containing a test header directive,
 /// which [`iter_header`] passes to its callback function.
 ///
@@ -783,7 +787,7 @@ pub(crate) struct CheckDirectiveResult<'ln> {
 
 pub(crate) fn check_directive<'a>(
     directive_ln: &'a str,
-    is_rustdoc: bool,
+    mode: Mode,
     original_line: &str,
 ) -> CheckDirectiveResult<'a> {
     let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, ""));
@@ -791,9 +795,18 @@ pub(crate) fn check_directive<'a>(
     let trailing = post.trim().split_once(' ').map(|(pre, _)| pre).unwrap_or(post);
     let is_known = |s: &str| {
         KNOWN_DIRECTIVE_NAMES.contains(&s)
-            || (is_rustdoc
-                && original_line.starts_with("//@")
-                && KNOWN_RUSTDOC_DIRECTIVE_NAMES.contains(&s))
+            || match mode {
+                Mode::Rustdoc | Mode::RustdocJson => {
+                    original_line.starts_with("//@")
+                        && match mode {
+                            Mode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES,
+                            Mode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES,
+                            _ => unreachable!(),
+                        }
+                        .contains(&s)
+                }
+                _ => false,
+            }
     };
     let trailing_directive = {
         // 1. is the directive name followed by a space? (to exclude `:`)
@@ -875,7 +888,7 @@ fn iter_header(
                 let directive_ln = non_revisioned_directive_line.trim();
 
                 let CheckDirectiveResult { is_known_directive, trailing_directive, .. } =
-                    check_directive(directive_ln, mode == Mode::Rustdoc, ln);
+                    check_directive(directive_ln, mode, ln);
 
                 if !is_known_directive {
                     *poisoned = true;
@@ -928,7 +941,7 @@ fn iter_header(
             let rest = rest.trim_start();
 
             let CheckDirectiveResult { is_known_directive, directive_name, .. } =
-                check_directive(rest, mode == Mode::Rustdoc, ln);
+                check_directive(rest, mode, ln);
 
             if is_known_directive {
                 *poisoned = true;
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index 429c6151796..de94990b53e 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -66,14 +66,17 @@ impl CommandKind {
         };
 
         if !count {
-            print_err(&format!("Incorrect number of arguments to `@{}`", self), lineno);
+            print_err(&format!("Incorrect number of arguments to `{}`", self), lineno);
             return false;
         }
 
         if let CommandKind::Count = self {
             if args[1].parse::<usize>().is_err() {
                 print_err(
-                    &format!("Second argument to @count must be a valid usize (got `{}`)", args[1]),
+                    &format!(
+                        "Second argument to `count` must be a valid usize (got `{}`)",
+                        args[1]
+                    ),
                     lineno,
                 );
                 return false;
@@ -101,7 +104,8 @@ static LINE_PATTERN: OnceLock<Regex> = OnceLock::new();
 fn line_pattern() -> Regex {
     RegexBuilder::new(
         r#"
-        \s(?P<invalid>!?)@(?P<negated>!?)
+        //@\s+
+        (?P<negated>!?)
         (?P<cmd>[A-Za-z]+(?:-[A-Za-z]+)*)
         (?P<args>.*)$
     "#,
@@ -116,6 +120,10 @@ fn print_err(msg: &str, lineno: usize) {
     eprintln!("Invalid command: {} on line {}", msg, lineno)
 }
 
+// FIXME: This setup is temporary until we figure out how to improve this situation.
+//        See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
+include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/command-list.rs"));
+
 /// Get a list of commands from a file. Does the work of ensuring the commands
 /// are syntactically valid.
 fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
@@ -132,36 +140,22 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
         };
 
         let negated = cap.name("negated").unwrap().as_str() == "!";
-        let cmd = cap.name("cmd").unwrap().as_str();
 
-        let cmd = match cmd {
+        let cmd = match cap.name("cmd").unwrap().as_str() {
             "has" => CommandKind::Has,
             "count" => CommandKind::Count,
             "is" => CommandKind::Is,
             "ismany" => CommandKind::IsMany,
             "set" => CommandKind::Set,
-            _ => {
-                print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
+            // FIXME: See the comment above the `include!(...)`.
+            cmd if KNOWN_DIRECTIVE_NAMES.contains(&cmd) => continue,
+            cmd => {
+                print_err(&format!("Unrecognized command name `{cmd}`"), lineno);
                 errors = true;
                 continue;
             }
         };
 
-        if let Some(m) = cap.name("invalid") {
-            if m.as_str() == "!" {
-                print_err(
-                    &format!(
-                        "`!@{0}{1}`, (help: try with `@!{1}`)",
-                        if negated { "!" } else { "" },
-                        cmd,
-                    ),
-                    lineno,
-                );
-                errors = true;
-                continue;
-            }
-        }
-
         let args = cap.name("args").map_or(Some(vec![]), |m| shlex::split(m.as_str()));
 
         let args = match args {
@@ -197,19 +191,19 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
     let result = match command.kind {
         CommandKind::Has => {
             match command.args.len() {
-                // @has <jsonpath> = check path exists
+                // `has <jsonpath>`: Check that `jsonpath` exists.
                 1 => {
                     let val = cache.value();
                     let results = select(val, &command.args[0]).unwrap();
                     !results.is_empty()
                 }
-                // @has <jsonpath> <value> = check *any* item matched by path equals value
+                // `has <jsonpath> <value>`: Check *any* item matched by `jsonpath` equals `value`.
                 2 => {
                     let val = cache.value().clone();
                     let results = select(&val, &command.args[0]).unwrap();
                     let pat = string_to_value(&command.args[1], cache);
                     let has = results.contains(&pat.as_ref());
-                    // Give better error for when @has check fails
+                    // Give better error for when `has` check fails.
                     if !command.negated && !has {
                         return Err(CkError::FailedCheck(
                             format!(
@@ -227,8 +221,9 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
                 _ => unreachable!(),
             }
         }
+        // `ismany <path> <jsonpath> <value...>`
         CommandKind::IsMany => {
-            // @ismany <path> <jsonpath> <value>...
+            assert!(!command.negated, "`ismany` may not be negated");
             let (query, values) = if let [query, values @ ..] = &command.args[..] {
                 (query, values)
             } else {
@@ -236,7 +231,6 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
             };
             let val = cache.value();
             let got_values = select(val, &query).unwrap();
-            assert!(!command.negated, "`@!ismany` is not supported");
 
             // Serde json doesn't implement Ord or Hash for Value, so we must
             // use a Vec here. While in theory that makes setwize equality
@@ -265,8 +259,8 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
             }
             true
         }
+        // `count <jsonpath> <count>`: Check that `jsonpath` matches exactly `count` times.
         CommandKind::Count => {
-            // @count <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
             assert_eq!(command.args.len(), 2);
             let expected: usize = command.args[1].parse().unwrap();
             let val = cache.value();
@@ -287,8 +281,8 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
                 eq
             }
         }
+        // `has <jsonpath> <value>`: Check` *exactly one* item matched by `jsonpath`, and it equals `value`.
         CommandKind::Is => {
-            // @has <jsonpath> <value> = check *exactly one* item matched by path, and it equals value
             assert_eq!(command.args.len(), 2);
             let val = cache.value().clone();
             let results = select(&val, &command.args[0]).unwrap();
@@ -308,8 +302,9 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
                 is
             }
         }
+        // `set <name> = <jsonpath>`
         CommandKind::Set => {
-            // @set <name> = <jsonpath>
+            assert!(!command.negated, "`set` may not be negated");
             assert_eq!(command.args.len(), 3);
             assert_eq!(command.args[1], "=", "Expected an `=`");
             let val = cache.value().clone();
@@ -317,7 +312,7 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
             assert_eq!(
                 results.len(),
                 1,
-                "Expected 1 match for `{}` (because of @set): matched to {:?}",
+                "Expected 1 match for `{}` (because of `set`): matched to {:?}",
                 command.args[2],
                 results
             );
@@ -330,7 +325,7 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
                 }
                 _ => {
                     panic!(
-                        "Got multiple results in `@set` for `{}`: {:?}",
+                        "Got multiple results in `set` for `{}`: {:?}",
                         &command.args[2], results,
                     );
                 }
@@ -341,18 +336,14 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
     if result == command.negated {
         if command.negated {
             Err(CkError::FailedCheck(
-                format!(
-                    "`@!{} {}` matched when it shouldn't",
-                    command.kind,
-                    command.args.join(" ")
-                ),
+                format!("`!{} {}` matched when it shouldn't", command.kind, command.args.join(" ")),
                 command,
             ))
         } else {
             // FIXME: In the future, try 'peeling back' each step, and see at what level the match failed
             Err(CkError::FailedCheck(
                 format!(
-                    "`@{} {}` didn't match when it should",
+                    "`{} {}` didn't match when it should",
                     command.kind,
                     command.args.join(" ")
                 ),