uic: test suite and fixture

This commit is contained in:
mappu 2024-09-20 18:39:12 +12:00
parent 691b7c42ab
commit c6e3f924c3
3 changed files with 250 additions and 0 deletions

130
cmd/miqt-uic/testdata/fixture1.ui vendored Normal file
View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Dropdown:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>First</string>
</property>
</item>
<item>
<property name="text">
<string>Second</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Number:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
<item row="0" column="1">
<widget class="QTreeWidget" name="treeWidget">
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>29</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="action_New"/>
<addaction name="separator"/>
<addaction name="actionE_xit"/>
</widget>
<addaction name="menu_File"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dockWidget">
<property name="windowTitle">
<string>Dock Title</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCalendarWidget" name="calendarWidget"/>
</item>
</layout>
</widget>
</widget>
<action name="action_New">
<property name="text">
<string>&amp;New...</string>
</property>
</action>
<action name="actionE_xit">
<property name="text">
<string>E&amp;xit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

47
cmd/miqt-uic/uic_test.go Normal file
View File

@ -0,0 +1,47 @@
package main
import (
"bytes"
"encoding/xml"
"io/ioutil"
"testing"
)
func TestFixtureMarshalRoundtrip(t *testing.T) {
testFixture := func(fixtureFile string) {
in, err := ioutil.ReadFile(fixtureFile)
if err != nil {
t.Fatalf("ReadFile: %v", err)
}
in = bytes.Replace(in, []byte("\r"), []byte{}, -1) // Replace CRLF to LF
var parsed UiFile
err = xml.Unmarshal(in, &parsed)
if err != nil {
t.Fatalf("Unmarshal: %v", err)
}
ret, err := xml.MarshalIndent(parsed, "", " ")
if err != nil {
t.Fatalf("Marshal: %v", err)
}
// Make some minor changes to our generated file to more closely match
// Qt Designer's generated ui file
// - Prepend XML header
// - Convert to self-closing tags
ret = []byte(xml.Header + xmlConvertToSelfClosing(string(ret)) + "\n")
// Verify that the marshalled result matches the original identically,
// i.e. we did not miss any properties in our XML type definitions
if string(in) != string(ret) {
t.Errorf("Mismatch")
t.Log(lineDiff(string(in), string(ret)))
}
}
testFixture("testdata/fixture1.ui")
}

73
cmd/miqt-uic/util.go Normal file
View File

@ -0,0 +1,73 @@
package main
import (
"fmt"
"strings"
)
// lineDiff does some basic diagnostic printing to show where two files differ.
// It is not clever about resyncronizing runs of differences.
func lineDiff(a, b string) string {
aLines := strings.Split(a, "\n")
bLines := strings.Split(b, "\n")
var diff []string
aIdx := 0
bIdx := 0
for {
// Check if one-or both- files have reached the final line already
if aIdx == len(aLines) {
if bIdx == len(bLines) {
break
} else {
diff = append(diff, fmt.Sprintf("%d: < %q", bIdx, bLines[bIdx]))
bIdx++
continue
}
} else if bIdx == len(bLines) {
diff = append(diff, fmt.Sprintf("%d: > %q", aIdx, aLines[aIdx]))
aIdx++
continue
}
// Both have remaining lines
if aLines[aIdx] == bLines[bIdx] {
// Match OK
} else {
diff = append(diff, fmt.Sprintf("%d: < %q", bIdx, aLines[aIdx]))
diff = append(diff, fmt.Sprintf("%d: > %q", aIdx, bLines[bIdx]))
}
aIdx++
bIdx++
}
return strings.Join(diff, "\n")
}
// xmlConvertToSelfClosing converts a multiline XML file, where if a line
// consists of <foo ...></foo>, it is replaced with <foo />.
func xmlConvertToSelfClosing(input string) string {
lines := strings.Split(input, "\n")
for i, l := range lines {
tll := strings.TrimLeft(l, " \t")
indent := l[0 : len(l)-len(tll)]
spos := strings.IndexAny(tll, " >")
if spos == -1 {
continue
}
opentag := tll[0:spos]
closetag := "</" + opentag[1:] + ">"
if !strings.HasSuffix(tll, ">"+closetag) {
continue
}
tll = tll[0:len(tll)-len(closetag)-1] + "/>"
lines[i] = indent + tll
}
return strings.Join(lines, "\n")
}