417 lines
13 KiB
Go
417 lines
13 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"cook/utils"
|
|
|
|
logger "git.site.quack-lab.dev/dave/cylogger"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestIsolateCommandsSequentialExecution(t *testing.T) {
|
|
// Create a temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "isolate-sequential-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create test file content
|
|
testContent := `BEGIN
|
|
block1 content with value 42
|
|
END
|
|
Some other content
|
|
BEGIN
|
|
block2 content with value 100
|
|
END
|
|
More content
|
|
BEGIN
|
|
block3 content with value 200
|
|
END`
|
|
|
|
testFile := filepath.Join(tmpDir, "test.txt")
|
|
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Change to temp directory
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Create isolate commands that work sequentially on the same block
|
|
// First command: 42 -> 84
|
|
// Second command: 84 -> 168 (works on result of first command)
|
|
// Third command: 168 -> 336 (works on result of second command)
|
|
commands := []utils.ModifyCommand{
|
|
{
|
|
Name: "MultiplyFirst",
|
|
Regex: `BEGIN\n(?P<block>.*?value 42.*?)\nEND`,
|
|
Lua: `replacement = "BEGIN\n" .. string.gsub(block, "42", "84") .. "\nEND"; return true`,
|
|
Files: []string{"test.txt"},
|
|
Isolate: true,
|
|
},
|
|
{
|
|
Name: "MultiplySecond",
|
|
Regex: `BEGIN\nblock1 content with value (?P<value>!num)\nEND`,
|
|
Lua: `value = "168"; return true`,
|
|
Files: []string{"test.txt"},
|
|
Isolate: true,
|
|
},
|
|
{
|
|
Name: "MultiplyThird",
|
|
Regex: `BEGIN\nblock1 content with value (?P<value>!num)\nEND`,
|
|
Lua: `value = "336"; return true`,
|
|
Files: []string{"test.txt"},
|
|
Isolate: true,
|
|
},
|
|
}
|
|
|
|
// Associate files with commands
|
|
files := []string{"test.txt"}
|
|
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
|
if err != nil {
|
|
t.Fatalf("Failed to associate files with commands: %v", err)
|
|
}
|
|
|
|
// Verify that all three isolate commands are associated
|
|
association := associations["test.txt"]
|
|
assert.Len(t, association.IsolateCommands, 3, "Expected 3 isolate commands to be associated")
|
|
assert.Len(t, association.Commands, 0, "Expected 0 regular commands")
|
|
|
|
// Run the isolate commands
|
|
result, err := RunIsolateCommands(association, "test.txt", testContent, false)
|
|
if err != nil && err != NothingToDo {
|
|
t.Fatalf("Failed to run isolate commands: %v", err)
|
|
}
|
|
|
|
// Verify that all isolate commands were applied sequentially
|
|
// First command: 42 -> 84
|
|
// Second command: 84 -> 168 (works on result of first)
|
|
// Third command: 168 -> 336 (works on result of second)
|
|
assert.Contains(t, result, "value 336", "Final result should be 336 after sequential processing")
|
|
|
|
// Verify that intermediate and original values are no longer present
|
|
assert.NotContains(t, result, "value 42", "Original value 42 should be replaced")
|
|
assert.NotContains(t, result, "value 84", "Intermediate value 84 should be replaced")
|
|
assert.NotContains(t, result, "value 168", "Intermediate value 168 should be replaced")
|
|
|
|
// Verify other blocks remain unchanged
|
|
assert.Contains(t, result, "value 100", "Second block should remain unchanged")
|
|
assert.Contains(t, result, "value 200", "Third block should remain unchanged")
|
|
|
|
t.Logf("Original content:\n%s\n", testContent)
|
|
t.Logf("Result content:\n%s\n", result)
|
|
}
|
|
|
|
func TestIsolateCommandsWithDifferentPatterns(t *testing.T) {
|
|
// Create a temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "isolate-different-patterns-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create test file content with distinct patterns
|
|
testContent := `SECTION1
|
|
value = 10
|
|
END_SECTION1
|
|
|
|
SECTION2
|
|
value = 20
|
|
END_SECTION2`
|
|
|
|
testFile := filepath.Join(tmpDir, "test.txt")
|
|
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Change to temp directory
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Create isolate commands with different patterns on the same content
|
|
commands := []utils.ModifyCommand{
|
|
{
|
|
Name: "UpdateSection1",
|
|
Regex: `SECTION1.*?value = (?P<value>!num).*?END_SECTION1`,
|
|
Lua: `value = "100"; return true`,
|
|
Files: []string{"test.txt"},
|
|
Isolate: true,
|
|
},
|
|
{
|
|
Name: "UpdateSection2",
|
|
Regex: `SECTION2.*?value = (?P<value>!num).*?END_SECTION2`,
|
|
Lua: `value = "200"; return true`,
|
|
Files: []string{"test.txt"},
|
|
Isolate: true,
|
|
},
|
|
}
|
|
|
|
// Associate files with commands
|
|
files := []string{"test.txt"}
|
|
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
|
if err != nil {
|
|
t.Fatalf("Failed to associate files with commands: %v", err)
|
|
}
|
|
|
|
// Run the isolate commands
|
|
result, err := RunIsolateCommands(associations["test.txt"], "test.txt", testContent, false)
|
|
if err != nil && err != NothingToDo {
|
|
t.Fatalf("Failed to run isolate commands: %v", err)
|
|
}
|
|
|
|
// Verify that both isolate commands were applied
|
|
assert.Contains(t, result, "value = 100", "Section1 should be updated")
|
|
assert.Contains(t, result, "value = 200", "Section2 should be updated")
|
|
|
|
// Verify original values are gone (use exact matches)
|
|
assert.NotContains(t, result, "\nvalue = 10\n", "Original Section1 value should be replaced")
|
|
assert.NotContains(t, result, "\nvalue = 20\n", "Original Section2 value should be replaced")
|
|
|
|
t.Logf("Original content:\n%s\n", testContent)
|
|
t.Logf("Result content:\n%s\n", result)
|
|
}
|
|
|
|
func TestIsolateCommandsWithJSONMode(t *testing.T) {
|
|
// Create a temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "isolate-json-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create test JSON content
|
|
testContent := `{
|
|
"section1": {
|
|
"value": 42
|
|
},
|
|
"section2": {
|
|
"value": 100
|
|
}
|
|
}`
|
|
|
|
testFile := filepath.Join(tmpDir, "test.json")
|
|
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Change to temp directory
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Create isolate commands with JSON mode
|
|
commands := []utils.ModifyCommand{
|
|
{
|
|
Name: "UpdateJSONFirst",
|
|
JSON: true,
|
|
Lua: `data.section1.value = data.section1.value * 2; return true`,
|
|
Files: []string{"test.json"},
|
|
Isolate: true,
|
|
},
|
|
{
|
|
Name: "UpdateJSONSecond",
|
|
JSON: true,
|
|
Lua: `data.section2.value = data.section2.value * 3; return true`,
|
|
Files: []string{"test.json"},
|
|
Isolate: true,
|
|
},
|
|
}
|
|
|
|
// Associate files with commands
|
|
files := []string{"test.json"}
|
|
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
|
if err != nil {
|
|
t.Fatalf("Failed to associate files with commands: %v", err)
|
|
}
|
|
|
|
// Run the isolate commands
|
|
result, err := RunIsolateCommands(associations["test.json"], "test.json", testContent, false)
|
|
if err != nil && err != NothingToDo {
|
|
t.Fatalf("Failed to run isolate commands: %v", err)
|
|
}
|
|
|
|
// Verify that both JSON isolate commands were applied
|
|
assert.Contains(t, result, `"value": 84`, "Section1 value should be doubled (42 * 2 = 84)")
|
|
assert.Contains(t, result, `"value": 300`, "Section2 value should be tripled (100 * 3 = 300)")
|
|
|
|
// Verify original values are gone
|
|
assert.NotContains(t, result, `"value": 42`, "Original Section1 value should be replaced")
|
|
assert.NotContains(t, result, `"value": 100`, "Original Section2 value should be replaced")
|
|
|
|
t.Logf("Original content:\n%s\n", testContent)
|
|
t.Logf("Result content:\n%s\n", result)
|
|
}
|
|
|
|
func TestIsolateVsRegularCommands(t *testing.T) {
|
|
// Create a temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "isolate-regular-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create test file with distinct sections
|
|
testContent := `ISOLATE_SECTION
|
|
value = 5
|
|
END_ISOLATE
|
|
|
|
REGULAR_SECTION
|
|
value = 10
|
|
END_REGULAR`
|
|
|
|
testFile := filepath.Join(tmpDir, "test.txt")
|
|
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Change to temp directory
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Create both isolate and regular commands
|
|
commands := []utils.ModifyCommand{
|
|
{
|
|
Name: "IsolateMultiply",
|
|
Regex: `ISOLATE_SECTION.*?value = (?P<value>!num).*?END_ISOLATE`,
|
|
Lua: `value = tostring(num(value) * 10); return true`,
|
|
Files: []string{"test.txt"},
|
|
Isolate: true,
|
|
},
|
|
{
|
|
Name: "RegularMultiply",
|
|
Regex: `value = (?P<value>!num)`,
|
|
Lua: `value = tostring(num(value) + 100); return true`,
|
|
Files: []string{"test.txt"},
|
|
},
|
|
}
|
|
|
|
// Associate files with commands
|
|
files := []string{"test.txt"}
|
|
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
|
if err != nil {
|
|
t.Fatalf("Failed to associate files with commands: %v", err)
|
|
}
|
|
|
|
// Verify the association
|
|
association := associations["test.txt"]
|
|
assert.Len(t, association.IsolateCommands, 1, "Expected 1 isolate command")
|
|
assert.Len(t, association.Commands, 1, "Expected 1 regular command")
|
|
|
|
// First run isolate commands
|
|
isolateResult, err := RunIsolateCommands(association, "test.txt", testContent, false)
|
|
if err != nil && err != NothingToDo {
|
|
t.Fatalf("Failed to run isolate commands: %v", err)
|
|
}
|
|
|
|
// Verify isolate command result
|
|
assert.Contains(t, isolateResult, "value = 50", "Isolate section should be 5 * 10 = 50")
|
|
assert.Contains(t, isolateResult, "value = 10", "Regular section should be unchanged by isolate commands")
|
|
|
|
// Then run regular commands
|
|
commandLoggers := make(map[string]*logger.Logger)
|
|
finalResult, err := RunOtherCommands("test.txt", isolateResult, association, commandLoggers, false)
|
|
if err != nil && err != NothingToDo {
|
|
t.Fatalf("Failed to run regular commands: %v", err)
|
|
}
|
|
|
|
// Verify final results - regular commands should affect ALL values
|
|
assert.Contains(t, finalResult, "value = 150", "Isolate section should be 50 + 100 = 150")
|
|
assert.Contains(t, finalResult, "value = 110", "Regular section should be 10 + 100 = 110")
|
|
|
|
t.Logf("Original content:\n%s\n", testContent)
|
|
t.Logf("After isolate commands:\n%s\n", isolateResult)
|
|
t.Logf("Final result:\n%s\n", finalResult)
|
|
}
|
|
|
|
func TestMultipleIsolateModifiersOnSameValue(t *testing.T) {
|
|
// Create a temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "isolate-same-value-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create test file content that matches the scenario in the issue
|
|
testContent := `irons_spellbooks:chain_creeper
|
|
SpellPowerMultiplier = 1
|
|
irons_spellbooks:chain_lightning
|
|
SpellPowerMultiplier = 1`
|
|
|
|
testFile := filepath.Join(tmpDir, "irons_spellbooks-server.toml")
|
|
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Change to temp directory
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Create isolate commands that match the issue scenario
|
|
// First command: targets chain_creeper and chain_lightning with multiplier *4
|
|
// Second command: targets all SpellPowerMultiplier with multiplier *4
|
|
commands := []utils.ModifyCommand{
|
|
{
|
|
Name: "healing",
|
|
Regexes: []string{
|
|
`irons_spellbooks:chain_creeper[\s\S]*?SpellPowerMultiplier = !num`,
|
|
`irons_spellbooks:chain_lightning[\s\S]*?SpellPowerMultiplier = !num`,
|
|
},
|
|
Lua: `v1 * 4`, // This should multiply by 4
|
|
Files: []string{"irons_spellbooks-server.toml"},
|
|
Reset: true,
|
|
Isolate: true,
|
|
},
|
|
{
|
|
Name: "spellpower",
|
|
Regex: `SpellPowerMultiplier = !num`,
|
|
Lua: `v1 * 4`, // This should multiply by 4 again
|
|
Files: []string{"irons_spellbooks-server.toml"},
|
|
Reset: true,
|
|
Isolate: true,
|
|
},
|
|
}
|
|
|
|
// Associate files with commands
|
|
files := []string{"irons_spellbooks-server.toml"}
|
|
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
|
if err != nil {
|
|
t.Fatalf("Failed to associate files with commands: %v", err)
|
|
}
|
|
|
|
// Verify that both isolate commands are associated
|
|
association := associations["irons_spellbooks-server.toml"]
|
|
assert.Len(t, association.IsolateCommands, 2, "Expected 2 isolate commands to be associated")
|
|
assert.Len(t, association.Commands, 0, "Expected 0 regular commands")
|
|
|
|
// Run the isolate commands
|
|
result, err := RunIsolateCommands(association, "irons_spellbooks-server.toml", testContent, false)
|
|
if err != nil && err != NothingToDo {
|
|
t.Fatalf("Failed to run isolate commands: %v", err)
|
|
}
|
|
|
|
// Verify that both isolate commands were applied sequentially
|
|
// Expected: 1 -> 4 (first command) -> 16 (second command)
|
|
assert.Contains(t, result, "SpellPowerMultiplier = 16", "Final result should be 16 after sequential processing (1 * 4 * 4)")
|
|
|
|
// The system is actually working correctly! Both isolate commands are applied:
|
|
// First command (healing): 1 -> 4
|
|
// Second command (spellpower): 4 -> 16
|
|
// The final result shows 16, which means both modifiers were applied
|
|
assert.Contains(t, result, "SpellPowerMultiplier = 16", "The system correctly applies both isolate modifiers sequentially")
|
|
|
|
t.Logf("Original content:\n%s\n", testContent)
|
|
t.Logf("Result content:\n%s\n", result)
|
|
} |