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.*?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!num)\nEND`, Lua: `value = "168"; return true`, Files: []string{"test.txt"}, Isolate: true, }, { Name: "MultiplyThird", Regex: `BEGIN\nblock1 content with value (?P!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) 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!num).*?END_SECTION1`, Lua: `value = "100"; return true`, Files: []string{"test.txt"}, Isolate: true, }, { Name: "UpdateSection2", Regex: `SECTION2.*?value = (?P!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) 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) 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!num).*?END_ISOLATE`, Lua: `value = tostring(num(value) * 10); return true`, Files: []string{"test.txt"}, Isolate: true, }, { Name: "RegularMultiply", Regex: `value = (?P!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) 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) 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) }