1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#![allow(missing_docs)]
// Property tests for RUNTIME-092: Enum variable cast support (Issue #79)
//
// These tests use proptest to verify enum cast behavior across 10K+ random inputs
// Testing: enum variable casts, arithmetic operations, type conversions
//
// Test naming convention: test_property_runtime_092_<scenario>
use predicates::prelude::*;
use proptest::prelude::*;
/// Property test: Enum discriminants convert correctly to i32
#[test]
fn test_property_runtime_092_enum_to_i32() {
proptest!(|(disc0 in 0i64..10, disc1 in 10i64..20)| {
let code = format!(r"
enum TestEnum {{
Variant0 = {disc0},
Variant1 = {disc1},
}}
fun main() {{
let v0 = TestEnum::Variant0;
let v1 = TestEnum::Variant1;
let val0 = v0 as i32;
let val1 = v1 as i32;
println(val0);
println(val1);
}}
");
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("-e")
.arg(&code)
.timeout(std::time::Duration::from_secs(5))
.assert()
.success()
.stdout(predicate::str::contains(disc0.to_string()))
.stdout(predicate::str::contains(disc1.to_string()));
});
}
/// Property test: Enum casts in arithmetic expressions
#[test]
fn test_property_runtime_092_enum_arithmetic() {
proptest!(|(disc in 0i64..100, add_val in 1i64..10)| {
let code = format!(r"
enum Value {{
X = {disc},
}}
fun main() {{
let v = Value::X;
let result = (v as i32) + {add_val};
println(result);
}}
");
let expected = disc + add_val;
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("-e")
.arg(&code)
.timeout(std::time::Duration::from_secs(5))
.assert()
.success()
.stdout(predicate::str::contains(expected.to_string()));
});
}
/// Property test: Multiple enum variables with different discriminants
#[test]
fn test_property_runtime_092_multiple_variables() {
proptest!(|(d0 in 0i64..10, d1 in 10i64..20, d2 in 20i64..30)| {
let code = format!(r"
enum Status {{
A = {d0},
B = {d1},
C = {d2},
}}
fun main() {{
let a = Status::A;
let b = Status::B;
let c = Status::C;
println(a as i32);
println(b as i32);
println(c as i32);
}}
");
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("-e")
.arg(&code)
.timeout(std::time::Duration::from_secs(5))
.assert()
.success()
.stdout(predicate::str::contains(d0.to_string()))
.stdout(predicate::str::contains(d1.to_string()))
.stdout(predicate::str::contains(d2.to_string()));
});
}
/// Property test: Enum cast to different integer types (i32, i64, isize)
#[test]
fn test_property_runtime_092_multiple_int_types() {
proptest!(|(disc in 0i64..1000)| {
let code = format!(r"
enum Value {{
X = {disc},
}}
fun main() {{
let v = Value::X;
let as_i32 = v as i32;
let v2 = Value::X;
let as_i64 = v2 as i64;
let v3 = Value::X;
let as_isize = v3 as isize;
println(as_i32);
println(as_i64);
println(as_isize);
}}
");
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("-e")
.arg(&code)
.timeout(std::time::Duration::from_secs(5))
.assert()
.success()
.stdout(predicate::str::contains(disc.to_string()).count(3));
});
}
/// Property test: Enum casts preserve discriminant values through operations
#[test]
fn test_property_runtime_092_discriminant_preservation() {
proptest!(|(disc in 0i64..50)| {
let code = format!(r"
enum Priority {{
Level = {disc},
}}
fun main() {{
let p = Priority::Level;
let val1 = p as i32;
let p2 = Priority::Level;
let val2 = p2 as i32;
let sum = val1 + val2;
println(sum);
}}
");
let expected = disc * 2;
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("-e")
.arg(&code)
.timeout(std::time::Duration::from_secs(5))
.assert()
.success()
.stdout(predicate::str::contains(expected.to_string()));
});
}