Skip to content

Commit 7c23443

Browse files
authored
Any ordered tests (#973)
* Any ordered tests Fixes #972 * fix output for mailq * use diff * fix data: subgroup order
1 parent ee9856b commit 7c23443

File tree

4 files changed

+271
-44
lines changed

4 files changed

+271
-44
lines changed

sdk/test/compare-sse.sh

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
#!/bin/sh
2+
3+
# Usage: compare-sse.sh expected.txt actual.txt
4+
# Compares two SSE files allowing fields to be in any order
5+
# but preserving order within same prefix types
6+
7+
# Function for comparing SSE outputs with error display
8+
compare_sse_with_output() {
9+
expected="$1"
10+
actual="$2"
11+
12+
# Call the main comparison logic
13+
compare_sse "$expected" "$actual" || {
14+
echo "Difference between expected and actual output:"
15+
echo ""
16+
diff -u "$expected" "$actual" || true
17+
return 1
18+
}
19+
return 0
20+
}
21+
22+
# Main comparison function
23+
compare_sse() {
24+
if [ $# -ne 2 ]; then
25+
echo "Usage: $0 expected.txt actual.txt" >&2
26+
exit 1
27+
fi
28+
29+
expected="$1"
30+
actual="$2"
31+
32+
if [ ! -f "$expected" ]; then
33+
echo "Expected file not found: $expected" >&2
34+
exit 1
35+
fi
36+
37+
if [ ! -f "$actual" ]; then
38+
echo "Actual file not found: $actual" >&2
39+
exit 1
40+
fi
41+
42+
# Use awk to parse and compare SSE events
43+
awk '
44+
BEGIN {
45+
RS = "\n\n\n" # Events separated by double newlines
46+
FS = "\n" # Fields separated by single newlines
47+
event_count_1 = 0
48+
event_count_2 = 0
49+
}
50+
51+
# Process first file (expected)
52+
NR == FNR {
53+
if (NF > 0) {
54+
event_count_1++
55+
delete data_fields
56+
delete other_fields
57+
data_count = 0
58+
59+
# Parse fields and separate data fields from others
60+
for (i = 1; i <= NF; i++) {
61+
if ($i != "") {
62+
# Extract prefix (everything before first colon)
63+
prefix = $i
64+
sub(/:.*/, "", prefix)
65+
66+
if (prefix == "data") {
67+
# Extract subgroup (first word after "data: ")
68+
subgroup = $i
69+
sub(/^data: /, "", subgroup)
70+
sub(/ .*$/, "", subgroup)
71+
72+
# Store data fields with subgroup for sorting
73+
data_count++
74+
data_fields[data_count] = $i
75+
data_subgroups[data_count] = subgroup
76+
} else {
77+
# Store non-data fields by prefix
78+
if (!(prefix in other_fields)) {
79+
other_fields[prefix] = ""
80+
}
81+
if (other_fields[prefix] != "") {
82+
other_fields[prefix] = other_fields[prefix] "\n"
83+
}
84+
other_fields[prefix] = other_fields[prefix] $i
85+
}
86+
}
87+
}
88+
89+
# Store event data
90+
for (prefix in other_fields) {
91+
events_1[event_count_1, prefix] = other_fields[prefix]
92+
}
93+
94+
# Sort and store data fields
95+
if (data_count > 0) {
96+
# Create sorting indices based on subgroup, preserving order within subgroups
97+
for (i = 1; i <= data_count; i++) {
98+
sort_indices[i] = i
99+
}
100+
101+
# Sort indices by subgroup name
102+
for (i = 1; i <= data_count; i++) {
103+
for (j = i + 1; j <= data_count; j++) {
104+
if (data_subgroups[sort_indices[i]] > data_subgroups[sort_indices[j]]) {
105+
temp = sort_indices[i]
106+
sort_indices[i] = sort_indices[j]
107+
sort_indices[j] = temp
108+
}
109+
}
110+
}
111+
112+
# Join data fields in sorted order
113+
sorted_data = ""
114+
for (i = 1; i <= data_count; i++) {
115+
if (sorted_data != "") {
116+
sorted_data = sorted_data "\n"
117+
}
118+
sorted_data = sorted_data data_fields[sort_indices[i]]
119+
}
120+
events_1[event_count_1, "data"] = sorted_data
121+
}
122+
}
123+
next
124+
}
125+
126+
# Process second file (actual)
127+
{
128+
if (NF > 0) {
129+
event_count_2++
130+
delete data_fields
131+
delete other_fields
132+
data_count = 0
133+
134+
# Parse fields and separate data fields from others
135+
for (i = 1; i <= NF; i++) {
136+
if ($i != "") {
137+
# Extract prefix (everything before first colon)
138+
prefix = $i
139+
sub(/:.*/, "", prefix)
140+
141+
if (prefix == "data") {
142+
# Extract subgroup (first word after "data: ")
143+
subgroup = $i
144+
sub(/^data: /, "", subgroup)
145+
sub(/ .*$/, "", subgroup)
146+
147+
# Store data fields with subgroup for sorting
148+
data_count++
149+
data_fields[data_count] = $i
150+
data_subgroups[data_count] = subgroup
151+
} else {
152+
# Store non-data fields by prefix
153+
if (!(prefix in other_fields)) {
154+
other_fields[prefix] = ""
155+
}
156+
if (other_fields[prefix] != "") {
157+
other_fields[prefix] = other_fields[prefix] "\n"
158+
}
159+
other_fields[prefix] = other_fields[prefix] $i
160+
}
161+
}
162+
}
163+
164+
# Store event data
165+
for (prefix in other_fields) {
166+
events_2[event_count_2, prefix] = other_fields[prefix]
167+
}
168+
169+
# Sort and store data fields
170+
if (data_count > 0) {
171+
# Create sorting indices based on subgroup, preserving order within subgroups
172+
for (i = 1; i <= data_count; i++) {
173+
sort_indices[i] = i
174+
}
175+
176+
# Sort indices by subgroup name
177+
for (i = 1; i <= data_count; i++) {
178+
for (j = i + 1; j <= data_count; j++) {
179+
if (data_subgroups[sort_indices[i]] > data_subgroups[sort_indices[j]]) {
180+
temp = sort_indices[i]
181+
sort_indices[i] = sort_indices[j]
182+
sort_indices[j] = temp
183+
}
184+
}
185+
}
186+
187+
# Join data fields in sorted order
188+
sorted_data = ""
189+
for (i = 1; i <= data_count; i++) {
190+
if (sorted_data != "") {
191+
sorted_data = sorted_data "\n"
192+
}
193+
sorted_data = sorted_data data_fields[sort_indices[i]]
194+
}
195+
events_2[event_count_2, "data"] = sorted_data
196+
}
197+
}
198+
}
199+
200+
END {
201+
# Compare event counts
202+
if (event_count_1 != event_count_2) {
203+
print "Event count mismatch: expected " event_count_1 ", got " event_count_2 > "/dev/stderr"
204+
exit 1
205+
}
206+
207+
# Compare each event
208+
for (e = 1; e <= event_count_1; e++) {
209+
# Collect all prefixes from both events
210+
delete all_prefixes
211+
for (key in events_1) {
212+
split(key, parts, SUBSEP)
213+
if (parts[1] == e) {
214+
all_prefixes[parts[2]] = 1
215+
}
216+
}
217+
for (key in events_2) {
218+
split(key, parts, SUBSEP)
219+
if (parts[1] == e) {
220+
all_prefixes[parts[2]] = 1
221+
}
222+
}
223+
224+
# Compare fields for each prefix
225+
for (prefix in all_prefixes) {
226+
key1 = e SUBSEP prefix
227+
key2 = e SUBSEP prefix
228+
229+
# Check if prefix exists in both
230+
if (!(key1 in events_1) && !(key2 in events_2)) {
231+
continue
232+
}
233+
234+
if (!(key1 in events_1)) {
235+
print "Event " e ": missing prefix \"" prefix "\" in expected" > "/dev/stderr"
236+
exit 1
237+
}
238+
239+
if (!(key2 in events_2)) {
240+
print "Event " e ": missing prefix \"" prefix "\" in actual" > "/dev/stderr"
241+
exit 1
242+
}
243+
244+
# Compare field content
245+
if (events_1[key1] != events_2[key2]) {
246+
print "Event " e ": mismatch in \"" prefix "\" fields" > "/dev/stderr"
247+
print "Expected:" > "/dev/stderr"
248+
print events_1[key1] > "/dev/stderr"
249+
print "Actual:" > "/dev/stderr"
250+
print events_2[key2] > "/dev/stderr"
251+
exit 1
252+
}
253+
}
254+
}
255+
256+
# All matches
257+
exit 0
258+
}
259+
' "$expected" "$actual"
260+
}
261+
262+
# If script is called directly (not sourced), run the comparison
263+
if [ "${0##*/}" = "compare-sse.sh" ]; then
264+
compare_sse "$@"
265+
fi

sdk/test/normalize.sh

Lines changed: 0 additions & 32 deletions
This file was deleted.

sdk/test/test-get.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/sh
22

3+
. ./compare-sse.sh
4+
35
[ ! -f "$1/input.json" ] && echo "case $1 does not have input.json" && return 1
46
[ ! -f "$1/output.txt" ] && echo "case $1 does not have output.txt" && return 1
57

@@ -11,11 +13,6 @@ curl -sN --get -H "Accept: text/event-stream" -H "datastar-request: true" --data
1113

1214
[ ! -f "$1/testOutput.txt" ] && echo "case $1 failed: your server did not return anything" && return 1
1315

14-
./normalize.sh "$1/output.txt" >"$1/norm_output.txt"
15-
./normalize.sh "$1/testOutput.txt" >"$1/norm_testOutput.txt"
16-
17-
diff -q "$1/norm_output.txt" "$1/norm_testOutput.txt" || { exit 1; }
18-
19-
rm "$1/norm_output.txt" "$1/norm_testOutput.txt"
16+
compare_sse_with_output "$1/output.txt" "$1/testOutput.txt" || { exit 1; }
2017

2118
exit 0

sdk/test/test-post.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/sh
22

3+
. ./compare-sse.sh
4+
35
[ ! -f "$1/input.json" ] && echo "case $1 does not have input.json" && return 1
46
[ ! -f "$1/output.txt" ] && echo "case $1 does not have output.txt" && return 1
57

@@ -11,11 +13,6 @@ curl -sN -H "Accept: text/event-stream" -H "datastar-request: true" --json "$inp
1113

1214
[ ! -f "$1/testOutput.txt" ] && echo "case $1 failed: your server did not return anything" && return 1
1315

14-
./normalize.sh "$1/output.txt" >"$1/norm_output.txt"
15-
./normalize.sh "$1/testOutput.txt" >"$1/norm_testOutput.txt"
16-
17-
diff -q "$1/norm_output.txt" "$1/norm_testOutput.txt" || { exit 1; }
18-
19-
rm "$1/norm_output.txt" "$1/norm_testOutput.txt"
16+
compare_sse_with_output "$1/output.txt" "$1/testOutput.txt" || { exit 1; }
2017

2118
exit 0

0 commit comments

Comments
 (0)