use super::eval;
use tsrun::JsValue;
#[test]
fn test_enum_numeric_basic() {
assert_eq!(
eval(
r#"
enum Direction {
Up,
Down,
Left,
Right
}
Direction.Up
"#
),
JsValue::Number(0.0)
);
assert_eq!(
eval(
r#"
enum Direction { Up, Down, Left, Right }
Direction.Right
"#
),
JsValue::Number(3.0)
);
}
#[test]
fn test_enum_numeric_explicit_values() {
assert_eq!(
eval(
r#"
enum Status {
Pending = 10,
Active = 20,
Closed = 30
}
Status.Active
"#
),
JsValue::Number(20.0)
);
}
#[test]
fn test_enum_string_values() {
assert_eq!(
eval(
r#"
enum Color {
Red = "red",
Green = "green",
Blue = "blue"
}
Color.Green
"#
),
JsValue::from("green")
);
}
#[test]
fn test_enum_mixed_values() {
assert_eq!(
eval(
r#"
enum Mixed {
A = 0,
B = "hello",
C = 1
}
Mixed.B
"#
),
JsValue::from("hello")
);
}
#[test]
fn test_enum_reverse_mapping_numeric() {
assert_eq!(
eval(
r#"
enum Direction {
Up,
Down,
Left,
Right
}
Direction[0]
"#
),
JsValue::from("Up")
);
}
#[test]
fn test_enum_reverse_mapping_all_numeric() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down, Left, Right }
Direction[0] + "," + Direction[1] + "," + Direction[2] + "," + Direction[3]
"#
),
JsValue::from("Up,Down,Left,Right")
);
}
#[test]
fn test_enum_no_reverse_mapping_for_strings() {
assert_eq!(
eval(
r#"
enum Color {
Red = "red",
Green = "green"
}
Color["red"]
"#
),
JsValue::Undefined
);
}
#[test]
fn test_enum_object_keys_numeric() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Object.keys(Direction).sort().join(",")
"#
),
JsValue::from("0,1,Down,Up")
);
}
#[test]
fn test_enum_object_keys_string() {
assert_eq!(
eval(
r#"
enum Color {
Red = "red",
Green = "green"
}
Object.keys(Color).sort().join(",")
"#
),
JsValue::from("Green,Red")
);
}
#[test]
fn test_enum_object_values_numeric() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Object.values(Direction).length
"#
),
JsValue::Number(4.0) );
}
#[test]
fn test_enum_object_values_string() {
assert_eq!(
eval(
r#"
enum Color {
Red = "red",
Green = "green"
}
Object.values(Color).sort().join(",")
"#
),
JsValue::from("green,red")
);
}
#[test]
fn test_enum_is_mutable_like_object() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Direction.Up = 999;
Direction.Up
"#
),
JsValue::Number(999.0)
);
}
#[test]
fn test_enum_can_add_properties() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
(Direction as any).NewMember = 100;
(Direction as any).NewMember
"#
),
JsValue::Number(100.0)
);
}
#[test]
fn test_enum_for_in_numeric() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
let keys: string[] = [];
for (let k in Direction) {
keys.push(k);
}
keys.sort().join(",")
"#
),
JsValue::from("0,1,Down,Up")
);
}
#[test]
fn test_enum_for_in_string() {
assert_eq!(
eval(
r#"
enum Color {
Red = "red",
Green = "green"
}
let keys: string[] = [];
for (let k in Color) {
keys.push(k);
}
keys.sort().join(",")
"#
),
JsValue::from("Green,Red")
);
}
#[test]
fn test_enum_typeof() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
typeof Direction
"#
),
JsValue::from("object")
);
}
#[test]
fn test_enum_member_typeof() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
typeof Direction.Up
"#
),
JsValue::from("number")
);
assert_eq!(
eval(
r#"
enum Color { Red = "red" }
typeof Color.Red
"#
),
JsValue::from("string")
);
}
#[test]
fn test_const_enum_basic() {
assert_eq!(
eval(
r#"
const enum Direction { Up, Down }
Direction.Up
"#
),
JsValue::Number(0.0)
);
}
#[test]
fn test_enum_in_arithmetic() {
assert_eq!(
eval(
r#"
enum Bits {
Read = 1,
Write = 2,
Execute = 4
}
Bits.Read | Bits.Write | Bits.Execute
"#
),
JsValue::Number(7.0)
);
}
#[test]
fn test_enum_in_comparison() {
assert_eq!(
eval(
r#"
enum Status { A = 1, B = 2 }
Status.A < Status.B
"#
),
JsValue::Boolean(true)
);
assert_eq!(
eval(
r#"
enum Status { A = 1, B = 2 }
Status.A === 1
"#
),
JsValue::Boolean(true)
);
}
#[test]
fn test_enum_computed_from_prior_members() {
assert_eq!(
eval(
r#"
enum FileAccess {
None = 0,
Read = 1,
Write = 2,
ReadWrite = Read | Write
}
FileAccess.ReadWrite
"#
),
JsValue::Number(3.0)
);
}
#[test]
fn test_enum_json_stringify() {
let result = eval(
r#"
enum Direction { Up, Down }
let json = JSON.stringify(Direction);
json.includes("Up") && json.includes("Down")
"#,
);
assert_eq!(result, JsValue::Boolean(true));
}
#[test]
fn test_enum_has_object_prototype() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Direction.hasOwnProperty("Up")
"#
),
JsValue::Boolean(true)
);
}
#[test]
fn test_enum_tostring() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Direction.toString()
"#
),
JsValue::from("[object Object]")
);
}
#[test]
fn test_enum_negative_values() {
assert_eq!(
eval(
r#"
enum Temperature {
Cold = -10,
Warm = 20,
Hot = 40
}
Temperature.Cold
"#
),
JsValue::Number(-10.0)
);
}
#[test]
fn test_enum_negative_reverse_mapping() {
assert_eq!(
eval(
r#"
enum Temperature {
Cold = -10,
Warm = 20
}
Temperature[-10]
"#
),
JsValue::from("Cold")
);
}
#[test]
fn test_enum_float_values() {
assert_eq!(
eval(
r#"
enum Ratio {
Half = 0.5,
Quarter = 0.25
}
Ratio.Half
"#
),
JsValue::Number(0.5)
);
}
#[test]
fn test_enum_float_reverse_mapping() {
assert_eq!(
eval(
r#"
enum Ratio {
Half = 0.5,
Quarter = 0.25
}
Ratio[0.5]
"#
),
JsValue::from("Half")
);
}
#[test]
fn test_enum_auto_increment_after_explicit() {
assert_eq!(
eval(
r#"
enum Mixed {
A, // 0
B = 10, // 10
C, // 11
D // 12
}
Mixed.A.toString() + "," + Mixed.B + "," + Mixed.C + "," + Mixed.D
"#
),
JsValue::from("0,10,11,12")
);
}
#[test]
fn test_enum_in_function_scope() {
assert_eq!(
eval(
r#"
function test(): number {
enum Local { A = 5 }
return Local.A;
}
test()
"#
),
JsValue::Number(5.0)
);
}
#[test]
fn test_enum_shadowing() {
assert_eq!(
eval(
r#"
enum X { A = 1 }
function test(): number {
enum X { A = 99 }
return X.A;
}
test() + X.A
"#
),
JsValue::Number(100.0) );
}
#[test]
fn test_enum_object_freeze() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Object.freeze(Direction);
Object.isFrozen(Direction)
"#
),
JsValue::Boolean(true)
);
}
#[test]
fn test_enum_object_keys_after_freeze() {
assert_eq!(
eval(
r#"
enum Direction { Up, Down }
Object.freeze(Direction);
Object.keys(Direction).length
"#
),
JsValue::Number(4.0) );
}
#[test]
fn test_enum_empty() {
assert_eq!(
eval(
r#"
enum Empty {}
Object.keys(Empty).length
"#
),
JsValue::Number(0.0)
);
}
#[test]
fn test_enum_single_member() {
assert_eq!(
eval(
r#"
enum Single { Only }
Single.Only
"#
),
JsValue::Number(0.0)
);
}
#[test]
fn test_enum_member_named_constructor() {
assert_eq!(
eval(
r#"
enum Special { constructor = 1 }
Special.constructor
"#
),
JsValue::Number(1.0)
);
}
#[test]
fn test_enum_member_named_prototype() {
assert_eq!(
eval(
r#"
enum Special { prototype = 1 }
Special.prototype
"#
),
JsValue::Number(1.0)
);
}