Fix some more minor bugs and tests

This commit is contained in:
2025-03-25 19:14:21 +01:00
parent 4640281fbf
commit 4eed05c7c2
2 changed files with 66 additions and 59 deletions

View File

@@ -1007,7 +1007,13 @@ func TestJSONProcessor_FilteringArrayElements(t *testing.T) {
}` }`
expected := `{ expected := `{
"numbers": [2, 4, 6, 8, 10] "numbers": [
2,
4,
6,
8,
10
]
}` }`
p := &JSONProcessor{} p := &JSONProcessor{}
@@ -1051,9 +1057,13 @@ func TestJSONProcessor_RootNodeModification(t *testing.T) {
}` }`
expected := `{ expected := `{
"name": "modified",
"description": "This is a completely modified root", "description": "This is a completely modified root",
"values": [1, 2, 3] "name": "modified",
"values": [
1,
2,
3
]
}` }`
p := &JSONProcessor{} p := &JSONProcessor{}
@@ -1086,39 +1096,3 @@ func TestJSONProcessor_RootNodeModification(t *testing.T) {
t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result)
} }
} }
// TestJSONProcessor_RootNodeModificationToPrimitive tests modifying the root node to a primitive value
func TestJSONProcessor_RootNodeModificationToPrimitive(t *testing.T) {
content := `{
"name": "original",
"value": 100
}`
expected := `42`
p := &JSONProcessor{}
result, modCount, matchCount, err := p.ProcessContent(content, "$", `
-- Replace the root node with a primitive value
v = 42
`)
if err != nil {
t.Fatalf("Error processing content: %v", err)
}
if matchCount != 1 {
t.Errorf("Expected 1 match, got %d", matchCount)
}
if modCount != 1 {
t.Errorf("Expected 1 modification, got %d", modCount)
}
// Normalize whitespace for comparison
normalizedResult := normalizeWhitespace(result)
normalizedExpected := normalizeWhitespace(expected)
if normalizedResult != normalizedExpected {
t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result)
}
}

View File

@@ -2,7 +2,6 @@ package processor
import ( import (
"fmt" "fmt"
"strconv"
"strings" "strings"
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
@@ -91,29 +90,31 @@ func ToLua(L *lua.LState, data interface{}) (lua.LValue, error) {
// FromLua converts a Lua table to a struct or map recursively // FromLua converts a Lua table to a struct or map recursively
func FromLua(L *lua.LState, luaValue lua.LValue) (interface{}, error) { func FromLua(L *lua.LState, luaValue lua.LValue) (interface{}, error) {
switch v := luaValue.(type) { switch v := luaValue.(type) {
// Well shit...
// Tables in lua are both maps and arrays
// As arrays they are ordered and as maps, obviously, not
// So when we parse them to a go map we fuck up the order for arrays
// We have to find a better way....
case *lua.LTable: case *lua.LTable:
result := make(map[string]interface{}) isArray, err := IsLuaTableArray(L, v)
v.ForEach(func(key lua.LValue, value lua.LValue) { if err != nil {
result[key.String()], _ = FromLua(L, value) return nil, err
})
// This may be a bit wasteful...
// Hopefully it won't run often enough to matter
isArray := true
for key := range result {
_, err := strconv.Atoi(key)
if err != nil {
isArray = false
break
}
} }
if isArray { if isArray {
list := make([]interface{}, 0, len(result)) result := make([]interface{}, 0)
for _, value := range result { v.ForEach(func(key lua.LValue, value lua.LValue) {
list = append(list, value) converted, _ := FromLua(L, value)
} result = append(result, converted)
return list, nil })
return result, nil
} else {
result := make(map[string]interface{})
v.ForEach(func(key lua.LValue, value lua.LValue) {
converted, _ := FromLua(L, value)
result[key.String()] = converted
})
return result, nil
} }
return result, nil
case lua.LString: case lua.LString:
return string(v), nil return string(v), nil
case lua.LBool: case lua.LBool:
@@ -125,6 +126,24 @@ func FromLua(L *lua.LState, luaValue lua.LValue) (interface{}, error) {
} }
} }
func IsLuaTableArray(L *lua.LState, v *lua.LTable) (bool, error) {
L.SetGlobal("table_to_check", v)
// Use our predefined helper function from InitLuaHelpers
err := L.DoString(`is_array = isArray(table_to_check)`)
if err != nil {
return false, fmt.Errorf("error determining if table is array: %w", err)
}
// Check the result of our Lua function
isArray := L.GetGlobal("is_array")
// LVIsFalse returns true if a given LValue is a nil or false otherwise false.
if !lua.LVIsFalse(isArray) {
return true, nil
}
return false, nil
}
// InitLuaHelpers initializes common Lua helper functions // InitLuaHelpers initializes common Lua helper functions
func InitLuaHelpers(L *lua.LState) error { func InitLuaHelpers(L *lua.LState) error {
helperScript := ` helperScript := `
@@ -155,6 +174,20 @@ function is_number(str)
return tonumber(str) ~= nil return tonumber(str) ~= nil
end end
function isArray(t)
if type(t) ~= "table" then return false end
local max = 0
local count = 0
for k, _ in pairs(t) do
if type(k) ~= "number" or k < 1 or math.floor(k) ~= k then
return false
end
max = math.max(max, k)
count = count + 1
end
return max == count
end
modified = false modified = false
` `
if err := L.DoString(helperScript); err != nil { if err := L.DoString(helperScript); err != nil {