Implement parsing xml to and from lua
A lot more complex than json.........
This commit is contained in:
@@ -5,6 +5,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"regexp"
|
||||
|
||||
"github.com/antchfx/xmlquery"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
// Helper function to normalize whitespace for comparison
|
||||
@@ -56,7 +59,7 @@ func TestXMLProcessor_Process_NodeValues(t *testing.T) {
|
||||
</catalog>`
|
||||
|
||||
p := &XMLProcessor{}
|
||||
result, modCount, matchCount, err := p.ProcessContent(content, "//price", "v = v * 2")
|
||||
result, modCount, matchCount, err := p.ProcessContent(content, "//price", "v.value = v.value * 2")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Error processing content: %v", err)
|
||||
@@ -1530,3 +1533,267 @@ func TestXMLProcessor_Process_DeepPathNavigation(t *testing.T) {
|
||||
|
||||
// Add more test cases for specific XML manipulation scenarios below
|
||||
// These tests would cover additional functionality as the implementation progresses
|
||||
|
||||
func TestXMLToLua(t *testing.T) {
|
||||
// Sample XML to test with
|
||||
xmlStr := `
|
||||
<root id="1">
|
||||
<person name="John" age="30">
|
||||
<address type="home">
|
||||
<street>123 Main St</street>
|
||||
<city>Anytown</city>
|
||||
<zip>12345</zip>
|
||||
</address>
|
||||
<contact type="email">john@example.com</contact>
|
||||
</person>
|
||||
<person name="Jane" age="28">
|
||||
<address type="work">
|
||||
<street>456 Business Ave</street>
|
||||
<city>Worktown</city>
|
||||
<zip>54321</zip>
|
||||
</address>
|
||||
<contact type="phone">555-1234</contact>
|
||||
</person>
|
||||
</root>
|
||||
`
|
||||
|
||||
// Parse the XML
|
||||
doc, err := xmlquery.Parse(strings.NewReader(xmlStr))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse XML: %v", err)
|
||||
}
|
||||
|
||||
// Create a new Lua state
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
|
||||
// Create an XML processor
|
||||
processor := &XMLProcessor{}
|
||||
|
||||
// Test converting the root element to Lua
|
||||
t.Run("RootElement", func(t *testing.T) {
|
||||
// Find the root element
|
||||
root := doc.SelectElement("root")
|
||||
if root == nil {
|
||||
t.Fatal("Failed to find root element")
|
||||
}
|
||||
|
||||
// Convert to Lua
|
||||
err := processor.ToLua(L, root)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to convert to Lua: %v", err)
|
||||
}
|
||||
|
||||
// Verify the result
|
||||
luaTable := L.GetGlobal("v")
|
||||
if luaTable.Type() != lua.LTTable {
|
||||
t.Fatalf("Expected table, got %s", luaTable.Type().String())
|
||||
}
|
||||
|
||||
// Check element type
|
||||
typeVal := L.GetField(luaTable, "type")
|
||||
if typeVal.String() != "element" {
|
||||
t.Errorf("Expected type 'element', got '%s'", typeVal.String())
|
||||
}
|
||||
|
||||
// Check name
|
||||
nameVal := L.GetField(luaTable, "name")
|
||||
if nameVal.String() != "root" {
|
||||
t.Errorf("Expected name 'root', got '%s'", nameVal.String())
|
||||
}
|
||||
|
||||
// Check attributes
|
||||
attrsTable := L.GetField(luaTable, "attributes")
|
||||
if attrsTable.Type() != lua.LTTable {
|
||||
t.Fatalf("Expected attributes table, got %s", attrsTable.Type().String())
|
||||
}
|
||||
|
||||
idVal := L.GetField(attrsTable, "id")
|
||||
if idVal.String() != "1" {
|
||||
t.Errorf("Expected id '1', got '%s'", idVal.String())
|
||||
}
|
||||
|
||||
// Check that we have children
|
||||
childrenTable := L.GetField(luaTable, "children")
|
||||
if childrenTable.Type() != lua.LTTable {
|
||||
t.Fatalf("Expected children table, got %s", childrenTable.Type().String())
|
||||
}
|
||||
})
|
||||
|
||||
// Test converting a nested element to Lua
|
||||
t.Run("NestedElement", func(t *testing.T) {
|
||||
// Find a nested element
|
||||
street := doc.SelectElement("//street")
|
||||
if street == nil {
|
||||
t.Fatal("Failed to find street element")
|
||||
}
|
||||
|
||||
// Convert to Lua
|
||||
err := processor.ToLua(L, street)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to convert to Lua: %v", err)
|
||||
}
|
||||
|
||||
// Verify the result
|
||||
luaTable := L.GetGlobal("v")
|
||||
if luaTable.Type() != lua.LTTable {
|
||||
t.Fatalf("Expected table, got %s", luaTable.Type().String())
|
||||
}
|
||||
|
||||
// Check element type
|
||||
typeVal := L.GetField(luaTable, "type")
|
||||
if typeVal.String() != "element" {
|
||||
t.Errorf("Expected type 'element', got '%s'", typeVal.String())
|
||||
}
|
||||
|
||||
// Check name
|
||||
nameVal := L.GetField(luaTable, "name")
|
||||
if nameVal.String() != "street" {
|
||||
t.Errorf("Expected name 'street', got '%s'", nameVal.String())
|
||||
}
|
||||
|
||||
// Check value
|
||||
valueVal := L.GetField(luaTable, "value")
|
||||
if valueVal.String() != "123 Main St" {
|
||||
t.Errorf("Expected value '123 Main St', got '%s'", valueVal.String())
|
||||
}
|
||||
})
|
||||
|
||||
// Test FromLua with a simple string update
|
||||
t.Run("FromLuaString", func(t *testing.T) {
|
||||
// Set up a Lua state with a string value
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
L.SetGlobal("v", lua.LString("New Value"))
|
||||
|
||||
// Convert from Lua
|
||||
result, err := processor.FromLua(L)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to convert from Lua: %v", err)
|
||||
}
|
||||
|
||||
// Verify the result
|
||||
strResult, ok := result.(string)
|
||||
if !ok {
|
||||
t.Fatalf("Expected string result, got %T", result)
|
||||
}
|
||||
|
||||
if strResult != "New Value" {
|
||||
t.Errorf("Expected 'New Value', got '%s'", strResult)
|
||||
}
|
||||
})
|
||||
|
||||
// Test FromLua with a complex table update
|
||||
t.Run("FromLuaTable", func(t *testing.T) {
|
||||
// Set up a Lua state with a table value
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
|
||||
table := L.NewTable()
|
||||
L.SetField(table, "value", lua.LString("Updated Text"))
|
||||
|
||||
attrTable := L.NewTable()
|
||||
L.SetField(attrTable, "id", lua.LString("new-id"))
|
||||
L.SetField(attrTable, "class", lua.LString("highlight"))
|
||||
|
||||
L.SetField(table, "attributes", attrTable)
|
||||
L.SetGlobal("v", table)
|
||||
|
||||
// Convert from Lua
|
||||
result, err := processor.FromLua(L)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to convert from Lua: %v", err)
|
||||
}
|
||||
|
||||
// Verify the result
|
||||
mapResult, ok := result.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("Expected map result, got %T", result)
|
||||
}
|
||||
|
||||
// Check value
|
||||
if value, ok := mapResult["value"]; !ok || value != "Updated Text" {
|
||||
t.Errorf("Expected value 'Updated Text', got '%v'", value)
|
||||
}
|
||||
|
||||
// Check attributes
|
||||
attrs, ok := mapResult["attributes"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("Expected attributes map, got %T", mapResult["attributes"])
|
||||
}
|
||||
|
||||
if id, ok := attrs["id"]; !ok || id != "new-id" {
|
||||
t.Errorf("Expected id 'new-id', got '%v'", id)
|
||||
}
|
||||
|
||||
if class, ok := attrs["class"]; !ok || class != "highlight" {
|
||||
t.Errorf("Expected class 'highlight', got '%v'", class)
|
||||
}
|
||||
})
|
||||
|
||||
// Test updateNodeFromMap with a simple value update
|
||||
t.Run("UpdateNodeValue", func(t *testing.T) {
|
||||
// Create a simple element to update
|
||||
xmlStr := `<test>Original Text</test>`
|
||||
doc, _ := xmlquery.Parse(strings.NewReader(xmlStr))
|
||||
node := doc.SelectElement("test")
|
||||
|
||||
// Create update data
|
||||
updateData := map[string]interface{}{
|
||||
"value": "Updated Text",
|
||||
}
|
||||
|
||||
// Update the node
|
||||
updateNodeFromMap(node, updateData)
|
||||
|
||||
// Verify the update
|
||||
if node.InnerText() != "Updated Text" {
|
||||
t.Errorf("Expected value 'Updated Text', got '%s'", node.InnerText())
|
||||
}
|
||||
})
|
||||
|
||||
// Test updateNodeFromMap with attribute updates
|
||||
t.Run("UpdateNodeAttributes", func(t *testing.T) {
|
||||
// Create an element with attributes
|
||||
xmlStr := `<test id="old">Text</test>`
|
||||
doc, _ := xmlquery.Parse(strings.NewReader(xmlStr))
|
||||
node := doc.SelectElement("test")
|
||||
|
||||
// Create update data
|
||||
updateData := map[string]interface{}{
|
||||
"attributes": map[string]interface{}{
|
||||
"id": "new",
|
||||
"class": "added",
|
||||
},
|
||||
}
|
||||
|
||||
// Update the node
|
||||
updateNodeFromMap(node, updateData)
|
||||
|
||||
// Verify the id attribute was updated
|
||||
idFound := false
|
||||
classFound := false
|
||||
for _, attr := range node.Attr {
|
||||
if attr.Name.Local == "id" {
|
||||
idFound = true
|
||||
if attr.Value != "new" {
|
||||
t.Errorf("Expected id 'new', got '%s'", attr.Value)
|
||||
}
|
||||
}
|
||||
if attr.Name.Local == "class" {
|
||||
classFound = true
|
||||
if attr.Value != "added" {
|
||||
t.Errorf("Expected class 'added', got '%s'", attr.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !idFound {
|
||||
t.Error("Expected to find 'id' attribute but didn't")
|
||||
}
|
||||
|
||||
if !classFound {
|
||||
t.Error("Expected to find 'class' attribute but didn't")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user