Skip to content

Commit 1509b78

Browse files
committed
Fix tests on windows, add javadoc
1 parent 2089ced commit 1509b78

4 files changed

Lines changed: 78 additions & 49 deletions

File tree

native-lib/example_dataweave_module.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,52 +23,52 @@ def example_simple_functions():
2323
ok = True
2424

2525
# Simple script execution
26-
print("\n📝 Simple arithmetic:")
26+
print("\n[*] Simple arithmetic:")
2727
script = "2 + 2"
2828
result = dataweave.run_script(script)
2929
ok = assert_result(script, result, "4") and ok
3030

31-
print("\n📝 Square root:")
31+
print("\n[*] Square root:")
3232
script = "sqrt(144)"
3333
result = dataweave.run_script(script)
3434
ok = assert_result(script, result, "12") and ok
3535

36-
print("\n📝 Array operations:")
36+
print("\n[*] Array operations:")
3737
script = "[1, 2, 3] map $ * 2"
3838
result = dataweave.run_script(script)
3939
ok = assert_result(script, result, "[\n 2, \n 4, \n 6\n]") and ok
4040

41-
print("\n📝 String operations:")
41+
print("\n[*] String operations:")
4242
script = "upper('hello world')"
4343
result = dataweave.run_script(script)
4444
ok = assert_result(script, result, '"HELLO WORLD"') and ok
4545

4646
# Script with inputs (simple values - auto-converted)
47-
print("\n📝 Script with inputs (auto-converted):")
47+
print("\n[*] Script with inputs (auto-converted):")
4848
script = "num1 + num2"
4949
result = dataweave.run_script(script, {"num1": 25, "num2": 17})
5050
ok = assert_result(script, result, "42") and ok
5151

5252
# Script with complex inputs
53-
print("\n📝 Script with complex object:")
53+
print("\n[*] Script with complex object:")
5454
script = "payload.name"
5555
result = dataweave.run_script(script, {"payload": {"content": '{"name": "John", "age": 30}', "mimeType": "application/json"}})
5656
ok = assert_result(script, result, '"John"') and ok
5757

5858
# Script with mixed input types
59-
print("\n📝 Script with mixed input types:")
59+
print("\n[*] Script with mixed input types:")
6060
script = "greeting ++ ' ' ++ payload.name"
6161
result = dataweave.run_script(script, {"greeting": "Hello", "payload": {"content": '{"name": "Alice", "role": "Developer"}', "mimeType": "application/json"}})
6262
ok = assert_result(script, result, '"Hello Alice"') and ok
6363

6464
# Binary output
65-
print("\n📝 Binary output:")
65+
print("\n[*] Binary output:")
6666
script = "output application/octet-stream\n---\ndw::core::Binaries::fromBase64(\"holamund\")"
6767
result = dataweave.run_script(script)
6868
ok = assert_result(script, result, "holamund") and ok
6969

7070
# Script with InputValue
71-
print("\n📝 Inputs:")
71+
print("\n[*] Inputs:")
7272
input_value = dataweave.InputValue(
7373
content="1234567",
7474
mimeType="application/csv",
@@ -80,7 +80,7 @@ def example_simple_functions():
8080

8181
# Cleanup when done
8282
dataweave.cleanup()
83-
print("\n Cleanup completed")
83+
print("\n[OK] Cleanup completed")
8484

8585
return ok
8686

@@ -89,9 +89,9 @@ def assert_result(script, result, expected):
8989
print(f" {script} = {result}")
9090
ok = result.get_string() == expected
9191
if ok:
92-
status = ""
92+
status = "[OK]"
9393
else:
94-
status = f" (expected: {expected})"
94+
status = f"[FAIL] (expected: {expected})"
9595
print(f" result as string = {result.get_string()} {status}")
9696
print(f" result as bytes = {result.get_bytes()}")
9797
return ok
@@ -106,7 +106,7 @@ def example_context_manager():
106106
ok = True
107107

108108
with dataweave.DataWeave() as dw:
109-
print("\n📝 Multiple operations with same runtime:")
109+
print("\n[*] Multiple operations with same runtime:")
110110

111111
script = "2 + 2"
112112
result = dw.run(script)
@@ -120,7 +120,7 @@ def example_context_manager():
120120
result = dw.run(script, {"numbers": [1, 2, 3, 4, 5], "multiplier": 10})
121121
ok = assert_result(script, result, "[\n 10, \n 20, \n 30, \n 40, \n 50\n]") and ok
122122

123-
print("\n Context manager automatically cleaned up resources")
123+
print("\n[OK] Context manager automatically cleaned up resources")
124124

125125
return ok
126126

@@ -131,7 +131,7 @@ def example_explicit_format():
131131
print("Example 3: Explicit Format (Advanced)")
132132
print("="*70)
133133

134-
print("\n📝 Using explicit content and mimeType:")
134+
print("\n[*] Using explicit content and mimeType:")
135135

136136
ok = True
137137

@@ -153,15 +153,15 @@ def example_error_handling():
153153
print("="*70)
154154

155155
try:
156-
print("\n📝 Invalid script (will show error):")
156+
print("\n[*] Invalid script (will show error):")
157157
result = dataweave.run_script("invalid syntax here", {})
158-
print(f" Result: {result} {'' if result.success == False else ''}")
158+
print(f" Result: {result} {'[OK]' if result.success == False else '[FAIL]'}")
159159

160160
except dataweave.DataWeaveLibraryNotFoundError as e:
161-
print(f" Library not found: {e}")
161+
print(f"[ERROR] Library not found: {e}")
162162
print(" Please build the library first: ./gradlew nativeCompile")
163163
except dataweave.DataWeaveError as e:
164-
print(f" DataWeave error: {e}")
164+
print(f"[ERROR] DataWeave error: {e}")
165165

166166

167167
def main():
@@ -181,17 +181,17 @@ def main():
181181

182182
print("\n" + "="*70)
183183
if all_ok:
184-
print(" All examples completed successfully!")
184+
print("[OK] All examples completed successfully!")
185185
else:
186-
print(" One or more examples failed")
186+
print("[FAIL] One or more examples failed")
187187
print("="*70)
188188

189189
except dataweave.DataWeaveLibraryNotFoundError as e:
190-
print(f"\n❌ Error: {e}")
190+
print(f"\n[ERROR] {e}")
191191
print("\nPlease build the native library first:")
192192
print(" ./gradlew nativeCompile")
193193
except Exception as e:
194-
print(f"\n Unexpected error: {e}")
194+
print(f"\n[ERROR] Unexpected error: {e}")
195195
import traceback
196196
traceback.print_exc()
197197

native-lib/python/tests/test_dataweave_module.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ def test_basic():
1717
try:
1818
result = dataweave.run_script("2 + 2", {})
1919
assert result.get_string() == "4", f"Expected '4', got '{result.get_string()}'"
20-
print(" Basic script execution works")
20+
print("[OK] Basic script execution works")
2121
return True
2222
except Exception as e:
23-
print(f" Basic script execution failed: {e}")
23+
print(f"[FAIL] Basic script execution failed: {e}")
2424
return False
2525

2626
def test_with_inputs():
@@ -29,10 +29,10 @@ def test_with_inputs():
2929
try:
3030
result = dataweave.run_script("num1 + num2", {"num1": 25, "num2": 17})
3131
assert result.get_string() == "42", f"Expected '42', got '{result.get_string()}'"
32-
print(" Script with inputs works")
32+
print("[OK] Script with inputs works")
3333
return True
3434
except Exception as e:
35-
print(f" Script with inputs failed: {e}")
35+
print(f"[FAIL] Script with inputs failed: {e}")
3636
return False
3737

3838
def test_context_manager():
@@ -45,10 +45,10 @@ def test_context_manager():
4545
assert result.get_string() == "12", f"Expected '12', got '{result.get_string()}'"
4646
result = dataweave.run_script("sqrt(10000)")
4747
assert result.get_string() == "100", f"Expected '100', got '{result.get_string()}'"
48-
print(" Script execution witch context manager works")
48+
print("[OK] Script execution witch context manager works")
4949
return True
5050
except Exception as e:
51-
print(f" Script execution witch context manager failed: {e}")
51+
print(f"[FAIL] Script execution witch context manager failed: {e}")
5252
return False
5353

5454
def test_encoding():
@@ -83,10 +83,10 @@ def test_encoding():
8383
assert "Billy" in out, f"Expected name 'Billy' in CSV, got: {out!r}"
8484
assert "31" in out, f"Expected age '31' in CSV, got: {out!r}"
8585

86-
print(" Encoding conversion works")
86+
print("[OK] Encoding conversion works")
8787
return True
8888
except Exception as e:
89-
print(f" Encoding conversion failed: {e}")
89+
print(f"[FAIL] Encoding conversion failed: {e}")
9090
return False
9191

9292
def test_auto_conversion():
@@ -101,10 +101,10 @@ def test_auto_conversion():
101101
)
102102
assert result.get_string() == "1", f"Expected '1', got '{result.get_string()}'"
103103

104-
print(" Auto-conversion works")
104+
print("[OK] Auto-conversion works")
105105
return True
106106
except Exception as e:
107-
print(f" Auto-conversion failed: {e}")
107+
print(f"[FAIL] Auto-conversion failed: {e}")
108108
return False
109109

110110
def main():
@@ -131,19 +131,19 @@ def main():
131131
print("="*70)
132132

133133
if passed == total:
134-
print("\n All tests passed!")
134+
print("\n[OK] All tests passed!")
135135
sys.exit(0)
136136
else:
137-
print(f"\n {total - passed} test(s) failed")
137+
print(f"\n[FAIL] {total - passed} test(s) failed")
138138
sys.exit(1)
139139

140140
except dataweave.DataWeaveLibraryNotFoundError as e:
141-
print(f"\n❌ Error: {e}")
141+
print(f"\n[ERROR] {e}")
142142
print("\nPlease build the native library first:")
143143
print(" ./gradlew nativeCompile")
144144
sys.exit(2)
145145
except Exception as e:
146-
print(f"\n Unexpected error: {e}")
146+
print(f"\n[ERROR] Unexpected error: {e}")
147147
import traceback
148148
traceback.print_exc()
149149
sys.exit(1)

native-lib/src/main/java/org/mule/weave/lib/NativeLib.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,21 @@
88

99
import java.nio.charset.StandardCharsets;
1010

11+
/**
12+
* GraalVM native entry points exposed for FFI consumers.
13+
*
14+
* <p>This class provides C-callable functions to execute DataWeave scripts and to free the returned
15+
* unmanaged strings.</p>
16+
*/
1117
public class NativeLib {
1218

1319
/**
14-
* TODO FIX documentation
1520
* Native method that executes a DataWeave script with inputs and returns the result.
1621
* Can be called from Python via FFI.
1722
*
18-
* Example JSON format:
19-
* {
20-
* "payload": {"content": "{\"field\": \"value\"}", "mimeType": "application/json"},
21-
* "vars": {"content": "test", "mimeType": "text/plain"}
22-
* }
23-
*
2423
* @param thread the isolate thread (automatically provided by GraalVM)
2524
* @param script the DataWeave script to execute (C string pointer)
26-
* @param inputsJson JSON string containing the inputs map with content and mimeType for each binding
25+
* @param inputsJson JSON string containing the inputs map with content (base64 encoded), mimeType, properties and charset for each binding
2726
* @return the script execution result (C string pointer)
2827
*/
2928
@CEntryPoint(name = "run_script")
@@ -36,6 +35,12 @@ public static CCharPointer runDwScriptEncoded(IsolateThread thread, CCharPointer
3635
return toUnmanagedCString(result);
3736
}
3837

38+
/**
39+
* Frees a C string previously returned by {@link #runDwScriptEncoded(IsolateThread, CCharPointer, CCharPointer)}.
40+
*
41+
* @param thread the isolate thread (automatically provided by GraalVM)
42+
* @param pointer the pointer to the unmanaged C string to free; if null, this is a no-op
43+
*/
3944
@CEntryPoint(name = "free_cstring")
4045
public static void freeCString(IsolateThread thread, CCharPointer pointer) {
4146
if (pointer.isNull()) {

native-lib/src/main/java/org/mule/weave/lib/ScriptRuntime.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,22 @@
1616
import java.nio.charset.Charset;
1717
import java.util.Base64;
1818

19+
/**
20+
* Singleton wrapper around a {@link DWScriptingEngine} used to compile and execute DataWeave scripts.
21+
*
22+
* <p>Execution results are returned as a JSON string containing a base64-encoded payload plus metadata
23+
* (mime type, charset, and whether the result is binary). Errors are returned as a JSON string with
24+
* {@code success=false} and an escaped error message.</p>
25+
*/
1926
public class ScriptRuntime {
2027

2128
private static final ScriptRuntime INSTANCE = new ScriptRuntime();
2229

30+
/**
31+
* Returns the singleton instance.
32+
*
33+
* @return the shared {@link ScriptRuntime}
34+
*/
2335
public static ScriptRuntime getInstance() {
2436
return INSTANCE;
2537
}
@@ -30,10 +42,26 @@ private ScriptRuntime() {
3042
engine = DWScriptingEngine.builder().build();
3143
}
3244

45+
/**
46+
* Executes a DataWeave script with no input bindings.
47+
*
48+
* @param script the DataWeave script source
49+
* @return a JSON string describing either the successful result or an error
50+
*/
3351
public String run(String script) {
3452
return run(script, null);
3553
}
3654

55+
/**
56+
* Executes a DataWeave script with optional input bindings encoded as JSON.
57+
*
58+
* <p>The expected JSON structure maps binding names to an object containing {@code content}
59+
* (base64), {@code mimeType}, optional {@code charset}, and optional {@code properties}.</p>
60+
*
61+
* @param script the DataWeave script source
62+
* @param inputsJson JSON string encoding the input bindings map, or {@code null}
63+
* @return a JSON string describing either the successful result or an error
64+
*/
3765
public String run(String script, String inputsJson) {
3866
ScriptingBindings bindings = parseJsonInputsToBindings(inputsJson);
3967
String[] inputs = bindings.bindingNames();
@@ -74,10 +102,6 @@ public String run(String script, String inputsJson) {
74102
}
75103
}
76104

77-
/**
78-
* Simple JSON parser for input map without external dependencies.
79-
* Expected format: {"name1": {"content": "value1", "mimeType": "type1", "charset": "charset1", "properties": {"prop1": "value1", "prop2": "value2"}}}
80-
*/
81105
private ScriptingBindings parseJsonInputsToBindings(String inputsJson) {
82106
ScriptingBindings bindings = new ScriptingBindings();
83107

0 commit comments

Comments
 (0)