use pasta_lua::{PastaLuaRuntime, TranspileContext};
use std::collections::HashMap;
fn create_test_context() -> TranspileContext {
let mut ctx = TranspileContext::new();
ctx.scene_registry.register_global("挨拶", HashMap::new());
ctx.scene_registry.register_global("会話", HashMap::new());
let (_, counter) = ctx.scene_registry.register_global("メイン", HashMap::new());
ctx.scene_registry
.register_local("選択肢", "メイン", counter, 1, HashMap::new());
ctx.word_registry.register_global(
"挨拶",
vec![
"こんにちは".to_string(),
"おはよう".to_string(),
"こんばんは".to_string(),
],
);
ctx.word_registry
.register_global("場所", vec!["東京".to_string(), "大阪".to_string()]);
ctx.word_registry
.register_local("メイン_1", "挨拶", vec!["やあ".to_string()]);
ctx
}
#[test]
fn test_runtime_creation() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx);
assert!(runtime.is_ok());
}
#[test]
fn test_require_pasta_search() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
return SEARCH ~= nil
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.as_boolean().unwrap_or(false));
}
#[test]
fn test_search_scene_global() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local global_name, local_name = SEARCH:search_scene("挨拶", nil)
return global_name
"#,
);
if let Err(ref e) = result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Expected Ok, got Err: {:?}", result);
let value = result.unwrap();
assert!(value.is_string());
}
#[test]
fn test_search_scene_not_found() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local global_name, local_name = SEARCH:search_scene("存在しないシーン", nil)
return global_name == nil
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.as_boolean().unwrap_or(false));
}
#[test]
fn test_search_word_global() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local word = SEARCH:search_word("挨拶", nil)
return word ~= nil
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.as_boolean().unwrap_or(false));
}
#[test]
fn test_search_word_local_fallback() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local word = SEARCH:search_word("挨拶", "メイン_1")
return word == "やあ"
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.as_boolean().unwrap_or(false));
}
#[test]
fn test_search_word_not_found() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local word = SEARCH:search_word("存在しない単語", nil)
return word == nil
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.as_boolean().unwrap_or(false));
}
#[test]
fn test_set_scene_selector() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
SEARCH:set_scene_selector(0, 1, 2)
return true
"#,
);
assert!(result.is_ok());
}
#[test]
fn test_set_word_selector() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
SEARCH:set_word_selector(0, 1, 2)
return true
"#,
);
assert!(result.is_ok());
}
#[test]
fn test_set_selector_reset() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
SEARCH:set_scene_selector()
SEARCH:set_word_selector()
return true
"#,
);
assert!(result.is_ok());
}
#[test]
fn test_multiple_runtime_instances() {
let ctx1 = create_test_context();
let ctx2 = create_test_context();
let runtime1 = PastaLuaRuntime::new(ctx1).unwrap();
let runtime2 = PastaLuaRuntime::new(ctx2).unwrap();
let result1 = runtime1.exec(
r#"
local SEARCH = require "@pasta_search"
return SEARCH:search_word("挨拶", nil)
"#,
);
let result2 = runtime2.exec(
r#"
local SEARCH = require "@pasta_search"
return SEARCH:search_word("場所", nil)
"#,
);
assert!(result1.is_ok());
assert!(result2.is_ok());
}
#[test]
fn test_require_returns_same_instance() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH1 = require "@pasta_search"
local SEARCH2 = require "@pasta_search"
return SEARCH1 == SEARCH2
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.as_boolean().unwrap_or(false));
}
#[test]
fn test_set_selector_invalid_argument() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
SEARCH:set_scene_selector("not an integer")
return true
"#,
);
assert!(result.is_err());
}
#[test]
fn test_search_scene_returns_transpiler_format() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local global_name, local_name = SEARCH:search_scene("挨拶", nil)
-- Verify format: global_name should be "挨拶_1", local_name should be "__start__"
return global_name == "挨拶_1" and local_name == "__start__"
"#,
);
assert!(result.is_ok(), "Expected Ok, got Err: {:?}", result);
let value = result.unwrap();
assert!(
value.as_boolean().unwrap_or(false),
"Expected global_name='挨拶_1' and local_name='__start__'"
);
}
#[test]
fn test_search_word_deterministic_with_mock_selector() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
SEARCH:set_word_selector(0)
local first = SEARCH:search_word("場所", nil)
local second = SEARCH:search_word("場所", nil)
return first == "東京" and second == "大阪"
"#,
);
assert!(result.is_ok(), "Expected Ok, got Err: {:?}", result);
let value = result.unwrap();
assert!(
value.as_boolean().unwrap_or(false),
"Expected deterministic word order 東京 → 大阪"
);
}
#[test]
fn test_search_word_global_not_visible_with_parent_scope() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local word = SEARCH:search_word("場所", "メイン_1")
return word == nil
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(
value.as_boolean().unwrap_or(false),
"Global-only word should not be found with a parent scope"
);
}
#[test]
fn test_search_scene_empty_name_raises_error() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local ok = pcall(function()
SEARCH:search_scene("", nil)
end)
return ok == false
"#,
);
assert!(result.is_ok());
let value = result.unwrap();
assert!(
value.as_boolean().unwrap_or(false),
"Empty scene name should raise a Lua error"
);
}
#[test]
fn test_search_scene_local_returns_transpiler_format() {
let ctx = create_test_context();
let runtime = PastaLuaRuntime::new(ctx).unwrap();
let result = runtime.exec(
r#"
local SEARCH = require "@pasta_search"
local global_name, local_name = SEARCH:search_scene("選択肢", "メイン_1")
-- Verify format: global_name should be "メイン_1", local_name should be "選択肢_1"
return global_name == "メイン_1" and local_name == "選択肢_1"
"#,
);
assert!(result.is_ok(), "Expected Ok, got Err: {:?}", result);
let value = result.unwrap();
assert!(
value.as_boolean().unwrap_or(false),
"Expected global_name='メイン_1' and local_name='選択肢_1'"
);
}