|
1 | 1 | """Integration test to demonstrate the environment variable feature""" |
2 | 2 | import os |
3 | | -import sys |
4 | | -import subprocess |
5 | | -import tempfile |
| 3 | +import pytest |
6 | 4 |
|
7 | 5 |
|
8 | | -def test_env_var_integration(): |
9 | | - """Integration test showing environment variables in action""" |
10 | | - # Create a simple test script that uses datar |
11 | | - test_script = """ |
12 | | -import os |
13 | | -from pipda import register_verb |
14 | | -from datar.core.verb_env import get_verb_ast_fallback |
| 6 | +def test_verb_ast_fallback_piping(): |
| 7 | + """Test that DATAR_*_AST_FALLBACK works with piping mode""" |
| 8 | + from pipda import register_verb |
| 9 | + from datar.core.verb_env import get_verb_ast_fallback |
| 10 | + |
| 11 | + # Set environment variable for piping mode |
| 12 | + os.environ['DATAR_PLUS_AST_FALLBACK'] = 'piping' |
| 13 | + |
| 14 | + try: |
| 15 | + # Register a simple verb |
| 16 | + @register_verb(ast_fallback=get_verb_ast_fallback("plus")) |
| 17 | + def plus(x, y): |
| 18 | + return x + y |
| 19 | + |
| 20 | + # Test with exec to disable source code detection at runtime |
| 21 | + # In piping mode, piping call should work |
| 22 | + result = {} |
| 23 | + exec("result['val'] = 1 >> plus(1)", {"plus": plus, "result": result}) |
| 24 | + assert result['val'] == 2 |
| 25 | + |
| 26 | + # Normal call in piping mode returns a placeholder when AST is not available |
| 27 | + result = {} |
| 28 | + exec("result['val'] = plus(1, 1)", {"plus": plus, "result": result}) |
| 29 | + # The result is a placeholder object, not the actual computation |
| 30 | + assert str(result['val']) == 'plus(., 1, 1)' |
| 31 | + |
| 32 | + finally: |
| 33 | + del os.environ['DATAR_PLUS_AST_FALLBACK'] |
| 34 | + |
| 35 | + |
| 36 | +def test_verb_ast_fallback_normal(): |
| 37 | + """Test that DATAR_*_AST_FALLBACK works with normal mode""" |
| 38 | + from pipda import register_verb |
| 39 | + from datar.core.verb_env import get_verb_ast_fallback |
| 40 | + |
| 41 | + # Set environment variable for normal mode |
| 42 | + os.environ['DATAR_MINUS_AST_FALLBACK'] = 'normal' |
| 43 | + |
| 44 | + try: |
| 45 | + # Register a simple verb |
| 46 | + @register_verb(ast_fallback=get_verb_ast_fallback("minus")) |
| 47 | + def minus(x, y): |
| 48 | + return x - y |
| 49 | + |
| 50 | + # Test with exec to disable source code detection at runtime |
| 51 | + # In normal mode, normal call should work |
| 52 | + result = {} |
| 53 | + exec("result['val'] = minus(5, 3)", {"minus": minus, "result": result}) |
| 54 | + assert result['val'] == 2 |
| 55 | + |
| 56 | + # Piping call in normal mode raises TypeError when AST is not available |
| 57 | + result = {} |
| 58 | + with pytest.raises(TypeError): |
| 59 | + exec("result['val'] = 5 >> minus(3)", {"minus": minus, "result": result}) |
15 | 60 |
|
16 | | -# Set environment variable before importing verbs |
17 | | -os.environ['DATAR_TEST_VERB_AST_FALLBACK'] = 'piping' |
| 61 | + finally: |
| 62 | + del os.environ['DATAR_MINUS_AST_FALLBACK'] |
18 | 63 |
|
19 | | -@register_verb(ast_fallback=get_verb_ast_fallback("test_verb")) |
20 | | -def test_verb(data): |
21 | | - return data |
22 | 64 |
|
23 | | -# Verify the verb is registered |
24 | | -assert callable(test_verb) |
25 | | -print("SUCCESS: Environment variable integration test passed") |
26 | | -""" |
| 65 | +def test_verb_ast_fallback_global(): |
| 66 | + """Test that DATAR_VERB_AST_FALLBACK works as global fallback""" |
| 67 | + from pipda import register_verb |
| 68 | + from datar.core.verb_env import get_verb_ast_fallback |
27 | 69 |
|
28 | | - # Write to a temporary file |
29 | | - with tempfile.NamedTemporaryFile( |
30 | | - mode='w', suffix='.py', delete=False |
31 | | - ) as f: |
32 | | - temp_path = f.name |
33 | | - f.write(test_script) |
| 70 | + # Set global environment variable |
| 71 | + os.environ['DATAR_VERB_AST_FALLBACK'] = 'piping' |
34 | 72 |
|
35 | 73 | try: |
36 | | - # Run the script |
37 | | - result = subprocess.run( |
38 | | - [sys.executable, temp_path], |
39 | | - capture_output=True, |
40 | | - text=True |
41 | | - ) |
42 | | - |
43 | | - # Check the result |
44 | | - assert result.returncode == 0 |
45 | | - assert "SUCCESS" in result.stdout |
| 74 | + # Register verbs without specific env var |
| 75 | + @register_verb(ast_fallback=get_verb_ast_fallback("multiply")) |
| 76 | + def multiply(x, y): |
| 77 | + return x * y |
| 78 | + |
| 79 | + @register_verb(ast_fallback=get_verb_ast_fallback("divide")) |
| 80 | + def divide(x, y): |
| 81 | + return x / y |
| 82 | + |
| 83 | + # Both should use global piping mode |
| 84 | + result = {} |
| 85 | + exec("result['mul'] = 6 >> multiply(2)", {"multiply": multiply, "result": result}) |
| 86 | + assert result['mul'] == 12 |
| 87 | + |
| 88 | + exec("result['div'] = 10 >> divide(2)", {"divide": divide, "result": result}) |
| 89 | + assert result['div'] == 5 |
| 90 | + |
| 91 | + finally: |
| 92 | + del os.environ['DATAR_VERB_AST_FALLBACK'] |
| 93 | + |
| 94 | + |
| 95 | +def test_verb_ast_fallback_precedence(): |
| 96 | + """Test that per-verb env var takes precedence over global""" |
| 97 | + from pipda import register_verb |
| 98 | + from datar.core.verb_env import get_verb_ast_fallback |
| 99 | + |
| 100 | + # Set global to piping and specific verb to normal |
| 101 | + os.environ['DATAR_VERB_AST_FALLBACK'] = 'piping' |
| 102 | + os.environ['DATAR_MODULO_AST_FALLBACK'] = 'normal' |
| 103 | + |
| 104 | + try: |
| 105 | + # Register verbs |
| 106 | + @register_verb(ast_fallback=get_verb_ast_fallback("power")) |
| 107 | + def power(x, y): |
| 108 | + return x ** y |
| 109 | + |
| 110 | + @register_verb(ast_fallback=get_verb_ast_fallback("modulo")) |
| 111 | + def modulo(x, y): |
| 112 | + return x % y |
| 113 | + |
| 114 | + # power should use global piping mode |
| 115 | + result = {} |
| 116 | + exec("result['pow'] = 2 >> power(3)", {"power": power, "result": result}) |
| 117 | + assert result['pow'] == 8 |
| 118 | + |
| 119 | + # modulo should use specific normal mode |
| 120 | + exec("result['mod'] = modulo(10, 3)", {"modulo": modulo, "result": result}) |
| 121 | + assert result['mod'] == 1 |
| 122 | + |
46 | 123 | finally: |
47 | | - # Clean up the temporary file |
48 | | - os.unlink(temp_path) |
| 124 | + del os.environ['DATAR_VERB_AST_FALLBACK'] |
| 125 | + del os.environ['DATAR_MODULO_AST_FALLBACK'] |
49 | 126 |
|
50 | 127 |
|
51 | 128 | if __name__ == "__main__": |
52 | | - test_env_var_integration() |
| 129 | + test_verb_ast_fallback_piping() |
| 130 | + test_verb_ast_fallback_normal() |
| 131 | + test_verb_ast_fallback_global() |
| 132 | + test_verb_ast_fallback_precedence() |
| 133 | + print("All integration tests passed!") |
0 commit comments