package processor import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" ) func TestLoadExternalLuaFile(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a test Lua file luaFile := filepath.Join(tmpDir, "test.lua") luaContent := `data.value = 42 modified = true` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) tests := []struct { name string luaPath string sourceDir string expected string wantError bool }{ { name: "Relative path with sourceDir", luaPath: "test.lua", sourceDir: tmpDir, expected: luaContent, wantError: false, }, { name: "Absolute path", luaPath: luaFile, sourceDir: "", expected: luaContent, wantError: false, }, { name: "Relative path without sourceDir (uses CWD)", luaPath: filepath.Base(luaFile), sourceDir: "", expected: luaContent, wantError: false, }, { name: "Nested relative path", luaPath: "scripts/test.lua", sourceDir: tmpDir, expected: "", wantError: true, }, { name: "Non-existent file", luaPath: "nonexistent.lua", sourceDir: tmpDir, expected: "", wantError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Change to tmpDir for CWD-based tests if tt.sourceDir == "" && !filepath.IsAbs(tt.luaPath) { origDir, _ := os.Getwd() defer os.Chdir(origDir) os.Chdir(tmpDir) } result, err := LoadExternalLuaFile(tt.luaPath, tt.sourceDir) if tt.wantError { assert.Error(t, err) assert.Empty(t, result) } else { assert.NoError(t, err) assert.Equal(t, tt.expected, result) } }) } } func TestBuildLuaScriptWithExternalFile(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-build-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a test Lua file luaFile := filepath.Join(tmpDir, "multiply.lua") luaContent := `v1 = v1 * 2` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) // Test with relative path relativePath := filepath.Base(luaFile) result := BuildLuaScript("@"+relativePath, tmpDir) assert.Contains(t, result, "v1 = v1 * 2") assert.Contains(t, result, "function run()") // Test with absolute path result = BuildLuaScript("@"+luaFile, "") assert.Contains(t, result, "v1 = v1 * 2") } func TestBuildLuaScriptWithExternalFileError(t *testing.T) { // Test that missing file returns error script result := BuildLuaScript("@nonexistent.lua", "/tmp") assert.Contains(t, result, "error(") assert.Contains(t, result, "Failed to load external Lua file") } func TestBuildJSONLuaScriptWithExternalFile(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-json-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a test Lua file luaFile := filepath.Join(tmpDir, "json_modify.lua") luaContent := `data.value = 84 modified = true` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) // Test with relative path relativePath := filepath.Base(luaFile) result := BuildJSONLuaScript("@"+relativePath, tmpDir) assert.Contains(t, result, "data.value = 84") assert.Contains(t, result, "modified = true") assert.Contains(t, result, "function run()") } func TestBuildLuaScriptWithInlineCode(t *testing.T) { // Test that inline code (without @) still works result := BuildLuaScript("v1 = v1 * 2", "") assert.Contains(t, result, "v1 = v1 * 2") assert.Contains(t, result, "function run()") assert.NotContains(t, result, "@") } func TestBuildLuaScriptExternalFileWithVariables(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-vars-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a test Lua file with variable reference luaFile := filepath.Join(tmpDir, "with_vars.lua") luaContent := `v1 = v1 * $multiply` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) // Set a global variable SetVariables(map[string]interface{}{"multiply": 1.5}) defer SetVariables(map[string]interface{}{}) // Test that variables are substituted in external files result := BuildLuaScript("@"+filepath.Base(luaFile), tmpDir) assert.Contains(t, result, "v1 = v1 * 1.5") assert.NotContains(t, result, "$multiply") } func TestBuildLuaScriptExternalFileNestedPath(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-nested-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create nested directory structure scriptsDir := filepath.Join(tmpDir, "scripts") err = os.MkdirAll(scriptsDir, 0755) assert.NoError(t, err) luaFile := filepath.Join(scriptsDir, "test.lua") luaContent := `data.value = 100` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) // Test with nested relative path result := BuildLuaScript("@scripts/test.lua", tmpDir) assert.Contains(t, result, "data.value = 100") } func TestBuildLuaScriptExternalFileWithPrependLuaAssignment(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-prepend-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a test Lua file with operator prefix (should trigger prepend) luaFile := filepath.Join(tmpDir, "multiply.lua") luaContent := `* 2` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) // Test that prepend still works with external files result := BuildLuaScript("@"+filepath.Base(luaFile), tmpDir) // PrependLuaAssignment adds "v1 = v1" + "* 2" = "v1 = v1* 2" (no space between v1 and *) assert.Contains(t, result, "v1 = v1* 2") } func TestBuildLuaScriptExternalFilePreservesWhitespace(t *testing.T) { tmpDir, err := os.MkdirTemp("", "lua-external-whitespace-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a test Lua file with multiline content luaFile := filepath.Join(tmpDir, "multiline.lua") luaContent := `if data.items then for i, item in ipairs(data.items) do item.value = item.value * 2 end modified = true end` err = os.WriteFile(luaFile, []byte(luaContent), 0644) assert.NoError(t, err) // Test that whitespace and formatting is preserved result := BuildLuaScript("@"+filepath.Base(luaFile), tmpDir) assert.Contains(t, result, "if data.items then") assert.Contains(t, result, " for i, item in ipairs(data.items) do") assert.Contains(t, result, " item.value = item.value * 2") }