mod common;
use common::must_ok;
use factorio_codegen::LuaGenerator;
use factorio_ir::{
block::Block,
expression::Expression,
function::{Function, Parameter},
module::{Module, Symbol},
scope::Scope,
stage::Stage,
statement::Statement,
structure::{Struct, StructField},
r#type::Type,
};
#[test]
fn generates_struct_as_table_with_methods() {
let module = Module {
name: "player".to_string(),
stage: Stage::Control,
body: Block { statements: vec![] },
imports: vec![],
submodules: vec![],
locales: vec![],
symbols: vec![Symbol {
scope: Scope::Public,
statement: Statement::StructDecl(Struct {
name: "MyPlayer".to_string(),
fields: vec![StructField {
name: "health".to_string(),
ty: Type::Int,
source_type: None,
}],
constants: vec![],
methods: vec![
Function {
name: "get_health".to_string(),
params: vec![Parameter {
name: "self".to_string(),
r#type: Type::Void,
source_type: None,
}],
body: Block {
statements: vec![Statement::Return(Some(Expression::FieldAccess {
base: Box::new(Expression::Identifier("self".to_string())),
field: "health".to_string(),
}))],
},
doc: None,
debug: None,
event: None,
event_filter: None,
},
Function {
name: "set_health".to_string(),
params: vec![
Parameter {
name: "self".to_string(),
r#type: Type::Void,
source_type: None,
},
Parameter {
name: "health".to_string(),
r#type: Type::Int,
source_type: None,
},
],
body: Block {
statements: vec![Statement::Assignment {
target: Expression::FieldAccess {
base: Box::new(Expression::Identifier("self".to_string())),
field: "health".to_string(),
},
value: Expression::Identifier("health".to_string()),
}],
},
doc: None,
debug: None,
event: None,
event_filter: None,
},
],
doc: None,
debug: None,
}),
}],
};
let output = must_ok(LuaGenerator::new().generate_module(&module));
assert_eq!(
output,
concat!(
"-- Generated by factorio-rs@0.1.0\n",
"-- Module: `player`\n",
"local player = {}\n",
"player.MyPlayer = {}\n",
"function player.MyPlayer:get_health()\n",
"\treturn self.health\n",
"end\n",
"function player.MyPlayer:set_health(health)\n",
"\tself.health = health\n",
"end\n",
"return player\n",
)
);
}
#[test]
fn generates_private_struct_as_local_table() {
let module = Module {
name: "player".to_string(),
stage: Stage::Control,
body: Block {
statements: vec![Statement::StructDecl(Struct {
name: "MyPlayer".to_string(),
fields: vec![],
constants: vec![],
methods: vec![Function {
name: "new".to_string(),
params: vec![],
body: Block { statements: vec![] },
doc: None,
debug: None,
event: None,
event_filter: None,
}],
doc: None,
debug: None,
})],
},
imports: vec![],
submodules: vec![],
locales: vec![],
symbols: vec![],
};
let output = must_ok(LuaGenerator::new().generate_module(&module));
assert!(output.contains("local MyPlayer = {}"));
assert!(output.contains("function MyPlayer.new()"));
}