Files
@ 392c59600687
Branch filter:
Location: CSY/reowolf/src/protocol/tests/eval_silly.rs
392c59600687
8.1 KiB
application/rls-services+xml
Test non-ascii string literals and recursion
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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | use super::*;
#[test]
fn test_concatenate_operator() {
Tester::new_single_source_expect_ok(
"concatenate and check values",
"
// Too see if we accept the polymorphic arg
func check_pair<T>(T[] arr, u32 idx) -> bool {
return arr[idx] == arr[idx + 1];
}
// Too see if we can check fields of polymorphs
func check_values<T>(T[] arr, u32 idx, u32 x, u32 y) -> bool {
auto value = arr[idx];
return value.x == x && value.y == y;
}
struct Point2D {
u32 x,
u32 y,
}
// Could do this inline, but we're attempt to stress the system a bit
func create_point(u32 x, u32 y) -> Point2D {
return Point2D{ x: x, y: y };
}
// Again, more stressing: returning a heap-allocated thing
func create_array() -> Point2D[] {
return {
create_point(1, 2),
create_point(1, 2),
create_point(3, 4),
create_point(3, 4)
};
}
// The silly checkamajig
func foo() -> bool {
auto lhs = create_array();
auto rhs = create_array();
auto total = lhs @ rhs;
auto is_equal =
check_pair(total, 0) &&
check_pair(total, 2) &&
check_pair(total, 4) &&
check_pair(total, 6);
auto is_not_equal =
!check_pair(total, 0) ||
!check_pair(total, 2) ||
!check_pair(total, 4) ||
!check_pair(total, 6);
auto has_correct_fields =
check_values(total, 3, 3, 4) &&
check_values(total, 4, 1, 2);
auto array_check = lhs == rhs && total == total;
return is_equal && !is_not_equal && has_correct_fields && array_check;
}
"
).for_function("foo", |f| {
f.call_ok(Some(Value::Bool(true)));
});
}
#[test]
fn test_slicing_magic() {
Tester::new_single_source_expect_ok("slicing", "
struct Holder<T> {
T[] left,
T[] right,
}
func create_array<T>(T first_index, T last_index) -> T[] {
auto result = {};
while (first_index < last_index) {
// Absolutely rediculous, but we don't have builtin array functions yet...
result = result @ { first_index };
first_index += 1;
}
return result;
}
func create_holder<T>(T left_first, T left_last, T right_first, T right_last) -> Holder<T> {
return Holder{
left: create_array(left_first, left_last),
right: create_array(right_first, right_last)
};
}
// Another silly thing, we first slice the full thing. Then subslice a single
// element, then concatenate. We always return an array of two things.
func slicing_magic<T>(Holder<T> holder, u32 left_base, u32 left_amount, u32 right_base, u32 right_amount) -> T[] {
auto left = holder.left[left_base..left_base + left_amount];
auto right = holder.right[right_base..right_base + right_amount];
return left[0..1] @ right[0..1];
}
func foo() -> bool {
// Preliminaries:
// 1. construct a holder, where:
// - left array will be [0, 1, 2, ...]
// - right array will be [2, 3, 4, ...]
// 2. Perform slicing magic, always returning an array [3, 3]
// 3. Make sure result is 6
// But ofcourse, because we want to be silly, we will check this for
// any possible integer type.
auto created_u08 = create_holder<u8> (0, 5, 2, 8);
auto created_u16 = create_holder<u16>(0, 5, 2, 8);
auto created_u32 = create_holder<u32>(0, 5, 2, 8);
auto created_u64 = create_holder<u64>(0, 5, 2, 8);
auto result_u08 = slicing_magic(created_u08, 3, 2, 1, 2);
auto result_u16 = slicing_magic(created_u16, 3, 2, 1, 2);
auto result_u32 = slicing_magic(created_u32, 3, 2, 1, 2);
auto result_u64 = slicing_magic(created_u64, 3, 2, 1, 2);
auto result_s08 = slicing_magic(create_holder<s8> (0, 5, 2, 8), 3, 2, 1, 2);
auto result_s16 = slicing_magic(create_holder<s16>(0, 5, 2, 8), 3, 2, 1, 2);
auto result_s32 = slicing_magic(create_holder<s32>(0, 5, 2, 8), 3, 2, 1, 2);
auto result_s64 = slicing_magic(create_holder<s64>(0, 5, 2, 8), 3, 2, 1, 2);
return
result_u08[0] + result_u08[1] == 6 &&
result_u16[0] + result_u16[1] == 6 &&
result_u32[0] + result_u32[1] == 6 &&
result_u64[0] + result_u64[1] == 6 &&
result_s08[0] + result_s08[1] == 6 &&
result_s16[0] + result_s16[1] == 6 &&
result_s32[0] + result_s32[1] == 6 &&
result_s64[0] + result_s64[1] == 6;
}
").for_function("foo", |f| {
f.call_ok(Some(Value::Bool(true)));
}).for_struct("Holder", |s| { s
.assert_num_monomorphs(8)
.assert_has_monomorph("u8")
.assert_has_monomorph("u16")
.assert_has_monomorph("u32")
.assert_has_monomorph("u64")
.assert_has_monomorph("s8")
.assert_has_monomorph("s16")
.assert_has_monomorph("s32")
.assert_has_monomorph("s64");
});
}
#[test]
fn test_struct_fields() {
Tester::new_single_source_expect_ok("struct field access", "
struct Nester<T> {
T v,
}
func make<T>(T inner) -> Nester<T> {
return Nester{ v: inner };
}
func modify<T>(Nester<T> outer, T inner) -> Nester<T> {
outer.v = inner;
return outer;
}
func foo() -> bool {
// Single depth modification
auto original1 = make<u32>(5);
auto modified1 = modify(original1, 2);
auto success1 = original1.v == 5 && modified1.v == 2;
// Multiple levels of modification
auto original2 = make(make(make(make(true))));
auto modified2 = modify(original2.v, make(make(false))); // strip one Nester level
auto success2 = original2.v.v.v.v == true && modified2.v.v.v == false;
return success1 && success2;
}
").for_function("foo", |f| {
f.call_ok(Some(Value::Bool(true)));
});
}
#[test]
fn test_field_selection_polymorphism() {
// Bit silly, but just to be sure
Tester::new_single_source_expect_ok("struct field shuffles", "
struct VecXYZ<T> { T x, T y, T z }
struct VecYZX<T> { T y, T z, T x }
struct VecZXY<T> { T z, T x, T y }
func modify_x<T>(T input) -> T {
input.x = 1337;
return input;
}
func foo() -> bool {
auto xyz = VecXYZ<u16>{ x: 1, y: 2, z: 3 };
auto yzx = VecYZX<u32>{ y: 2, z: 3, x: 1 };
auto zxy = VecZXY<u64>{ x: 1, y: 2, z: 3 }; // different initialization order
auto mod_xyz = modify_x(xyz);
auto mod_yzx = modify_x(yzx);
auto mod_zxy = modify_x(zxy);
return
xyz.x == 1 && xyz.y == 2 && xyz.z == 3 &&
yzx.x == 1 && yzx.y == 2 && yzx.z == 3 &&
zxy.x == 1 && zxy.y == 2 && zxy.z == 3 &&
mod_xyz.x == 1337 && mod_xyz.y == 2 && mod_xyz.z == 3 &&
mod_yzx.x == 1337 && mod_yzx.y == 2 && mod_yzx.z == 3 &&
mod_zxy.x == 1337 && mod_zxy.y == 2 && mod_zxy.z == 3;
}
").for_function("foo", |f| {
f.call_ok(Some(Value::Bool(true)));
});
}
#[test]
fn test_index_error() {
Tester::new_single_source_expect_ok("indexing error", "
func check_array(u32[] vals, u32 idx) -> u32 {
return vals[idx];
}
func foo() -> u32 {
auto array = {1, 2, 3, 4, 5, 6, 7};
check_array(array, 7);
return array[0];
}
").for_function("foo", |f| {
f.call_err("index 7 is out of bounds: array length is 7");
});
}
|