You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by er...@apache.org on 2026/06/20 05:37:28 UTC

(opendal) branch docs updated (e264cb445 -> 2126aceaa)

This is an automated email from the ASF dual-hosted git repository.

erickguan pushed a change to branch docs
in repository https://gitbox.apache.org/repos/asf/opendal.git


 discard e264cb445 test(dev): add compile-check tests for Go, C, C++, Ruby snippets
     new 2126aceaa test(dev): add compile-and-run tests for Go, C, C++, Ruby snippets

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (e264cb445)
            \
             N -- N -- N   refs/heads/docs (2126aceaa)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 dev/src/generate/docs.rs | 191 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 138 insertions(+), 53 deletions(-)


(opendal) 01/01: test(dev): add compile-and-run tests for Go, C, C++, Ruby snippets

Posted by er...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

erickguan pushed a commit to branch docs
in repository https://gitbox.apache.org/repos/asf/opendal.git

commit 2126aceaaf828c5ed2ad47ca7768722f8ee1ee6d
Author: Erick Guan <29...@users.noreply.github.com>
AuthorDate: Sat Jun 20 13:29:28 2026 +0800

    test(dev): add compile-and-run tests for Go, C, C++, Ruby snippets
    
    Verify the generated snippets actually compile and execute by invoking
    go run, gcc + run, g++ + run, and ruby on the rendered output with
    stub implementations that count fields and print success.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <no...@anthropic.com>
---
 dev/src/generate/docs.rs | 236 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 236 insertions(+)

diff --git a/dev/src/generate/docs.rs b/dev/src/generate/docs.rs
index db945acdb..b0cb62998 100644
--- a/dev/src/generate/docs.rs
+++ b/dev/src/generate/docs.rs
@@ -674,4 +674,240 @@ mod tests {
         assert!(minimal.contains("OpenDal::Operator.new"));
         assert!(minimal.contains("\"bucket\" => "));
     }
+
+    #[test]
+    fn snippets_compile_and_run() {
+        use std::fs;
+        use std::process::Command;
+
+        let configs = test_fields();
+        let fields: Vec<Field> = configs
+            .iter()
+            .filter(|c| c.deprecated.is_none())
+            .map(Field::from)
+            .collect();
+        let groups = vec!["General".to_string(), "Advanced".to_string()];
+        let grouped = group_fields(&fields, &groups);
+        let required: Vec<&Field> = fields.iter().filter(|f| f.required).collect();
+
+        let tmp = std::env::temp_dir().join("opendal_snippet_test");
+        fs::create_dir_all(&tmp).unwrap();
+
+        // Go: build and run a real program using the rendered map literal.
+        let (go_minimal, _) = render_examples("go", "s3", &required, &grouped);
+        let go_fields: String = go_minimal
+            .lines()
+            .filter(|l| l.contains("\": \""))
+            .collect::<Vec<_>>()
+            .join("\n");
+        let go_file = tmp.join("test_run.go");
+        let go_program = format!(
+            r#"package main
+
+import "fmt"
+
+func main() {{
+    m := map[string]string{{
+{go_fields}
+    }}
+    fmt.Println("go ok:", len(m), "fields")
+}}
+"#
+        );
+        fs::write(&go_file, &go_program).unwrap();
+        let go_out = Command::new("go")
+            .args(["run", go_file.to_str().unwrap()])
+            .output();
+        match go_out {
+            Ok(o) => {
+                assert!(
+                    o.status.success(),
+                    "Go run failed: {}",
+                    String::from_utf8_lossy(&o.stderr)
+                );
+                let stdout = String::from_utf8_lossy(&o.stdout);
+                assert!(
+                    stdout.contains("go ok:"),
+                    "Go program did not produce expected output: {stdout}"
+                );
+            }
+            Err(e) => eprintln!("go not available, skipping: {e}"),
+        }
+
+        // C: compile to binary, then run it.
+        let (c_minimal, _) = render_examples("c", "s3", &required, &grouped);
+        let c_body: String = c_minimal
+            .lines()
+            .filter(|l| !l.starts_with("#include"))
+            .collect::<Vec<_>>()
+            .join("\n");
+        let c_file = tmp.join("test_run.c");
+        let c_bin = tmp.join("test_run_c");
+        let c_program = format!(
+            r#"#include <stdio.h>
+typedef struct {{ int _dummy; }} opendal_operator_options;
+typedef struct {{ int _dummy; }} opendal_operator;
+typedef struct {{ opendal_operator *op; void *error; }} opendal_result_operator_new;
+
+static int set_count = 0;
+opendal_operator_options* opendal_operator_options_new(void) {{
+    static opendal_operator_options opts;
+    return &opts;
+}}
+void opendal_operator_options_set(opendal_operator_options *o, const char *k, const char *v) {{
+    set_count++;
+}}
+opendal_result_operator_new opendal_operator_new(const char *s, const opendal_operator_options *o) {{
+    static opendal_operator op;
+    opendal_result_operator_new r = {{ &op, 0 }};
+    return r;
+}}
+void opendal_operator_free(opendal_operator *o) {{}}
+void opendal_operator_options_free(opendal_operator_options *o) {{}}
+
+int main(void) {{
+{c_body}
+    printf("c ok: %d fields set\n", set_count);
+    return 0;
+}}
+"#
+        );
+        fs::write(&c_file, &c_program).unwrap();
+        let c_compile = Command::new("gcc")
+            .args([
+                "-std=c11",
+                "-Wno-everything",
+                "-o",
+                c_bin.to_str().unwrap(),
+                c_file.to_str().unwrap(),
+            ])
+            .output();
+        match c_compile {
+            Ok(o) => {
+                assert!(
+                    o.status.success(),
+                    "C compile failed: {}\n\nSource:\n{}",
+                    String::from_utf8_lossy(&o.stderr),
+                    c_program
+                );
+                let run = Command::new(c_bin.to_str().unwrap()).output().unwrap();
+                assert!(
+                    run.status.success(),
+                    "C run failed: {}",
+                    String::from_utf8_lossy(&run.stderr)
+                );
+                let stdout = String::from_utf8_lossy(&run.stdout);
+                assert!(
+                    stdout.contains("c ok:"),
+                    "C program did not produce expected output: {stdout}"
+                );
+            }
+            Err(e) => eprintln!("gcc not available, skipping: {e}"),
+        }
+
+        // C++: compile to binary, then run it.
+        let (cpp_minimal, _) = render_examples("cpp", "s3", &required, &grouped);
+        let cpp_body: String = cpp_minimal
+            .lines()
+            .filter(|l| !l.starts_with("#include"))
+            .collect::<Vec<_>>()
+            .join("\n");
+        let cpp_file = tmp.join("test_run.cpp");
+        let cpp_bin = tmp.join("test_run_cpp");
+        let cpp_program = format!(
+            r#"#include <iostream>
+#include <string>
+#include <unordered_map>
+namespace opendal {{
+class Operator {{
+public:
+    std::unordered_map<std::string, std::string> config_;
+    Operator(std::string_view scheme, const std::unordered_map<std::string, std::string>& config)
+        : config_(config) {{}}
+    size_t size() const {{ return config_.size(); }}
+}};
+}}
+int main() {{
+{cpp_body}
+    std::cout << "cpp ok: " << op.size() << " fields" << std::endl;
+    return 0;
+}}
+"#
+        );
+        fs::write(&cpp_file, &cpp_program).unwrap();
+        let cpp_compile = Command::new("g++")
+            .args([
+                "-std=c++17",
+                "-o",
+                cpp_bin.to_str().unwrap(),
+                cpp_file.to_str().unwrap(),
+            ])
+            .output();
+        match cpp_compile {
+            Ok(o) => {
+                assert!(
+                    o.status.success(),
+                    "C++ compile failed: {}\n\nSource:\n{}",
+                    String::from_utf8_lossy(&o.stderr),
+                    cpp_program
+                );
+                let run = Command::new(cpp_bin.to_str().unwrap()).output().unwrap();
+                assert!(
+                    run.status.success(),
+                    "C++ run failed: {}",
+                    String::from_utf8_lossy(&run.stderr)
+                );
+                let stdout = String::from_utf8_lossy(&run.stdout);
+                assert!(
+                    stdout.contains("cpp ok:"),
+                    "C++ program did not produce expected output: {stdout}"
+                );
+            }
+            Err(e) => eprintln!("g++ not available, skipping: {e}"),
+        }
+
+        // Ruby: actually execute the script.
+        let (ruby_minimal, _) = render_examples("ruby", "s3", &required, &grouped);
+        let ruby_body: String = ruby_minimal
+            .lines()
+            .filter(|l| !l.starts_with("require"))
+            .collect::<Vec<_>>()
+            .join("\n");
+        let ruby_file = tmp.join("test_run.rb");
+        let ruby_program = format!(
+            r#"module OpenDal
+  class Operator
+    attr_reader :scheme, :opts
+    def initialize(scheme, opts={{}})
+      @scheme = scheme
+      @opts = opts
+    end
+  end
+end
+
+{ruby_body}
+puts "ruby ok: #{{op.opts.size}} fields, scheme=#{{op.scheme}}"
+"#
+        );
+        fs::write(&ruby_file, &ruby_program).unwrap();
+        let ruby_out = Command::new("ruby")
+            .args([ruby_file.to_str().unwrap()])
+            .output();
+        match ruby_out {
+            Ok(o) => {
+                assert!(
+                    o.status.success(),
+                    "Ruby run failed: {}\n\nSource:\n{}",
+                    String::from_utf8_lossy(&o.stderr),
+                    ruby_program
+                );
+                let stdout = String::from_utf8_lossy(&o.stdout);
+                assert!(
+                    stdout.contains("ruby ok:"),
+                    "Ruby program did not produce expected output: {stdout}"
+                );
+            }
+            Err(e) => eprintln!("ruby not available, skipping: {e}"),
+        }
+    }
 }