-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiff.go
More file actions
91 lines (78 loc) · 2.5 KB
/
diff.go
File metadata and controls
91 lines (78 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package main
import "github.com/sergi/go-diff/diffmatchpatch"
func responseChanged(baselineResponses []ResponseData, new ResponseData, equalCheck bool, threshold float64) bool {
for _, baseline := range baselineResponses {
if equalCheck && responsesAreEqual(baseline, new) {
return false
} else if !equalCheck && responsesAreSimilar(baseline, new, threshold) {
return false
}
}
return true // Response is different from all baselines; significant change detected
}
// responseChangedIgnoringReflections checks if the response changed compared to
// baselines, but ignores the Reflections field. Used for testing form parameters
// that are already present in baseline HTML to avoid false positives.
func responseChangedIgnoringReflections(baselineResponses []ResponseData, new ResponseData, sameBody bool, threshold float64) bool {
for _, baseline := range baselineResponses {
if baseline.StatusCode != new.StatusCode {
continue
}
if sameBody {
if baseline.BodyHash == new.BodyHash {
return false
}
} else {
if baseline.BodyHash == new.BodyHash {
return false
}
similarity := computeSimilarity(baseline.Body, new.Body)
if similarity >= threshold {
return false
}
}
}
return true
}
func responsesAreSimilar(a, b ResponseData, threshold float64) bool {
similarity := 1.0
if a.BodyHash != b.BodyHash {
similarity = computeSimilarity(a.Body, b.Body)
}
return a.StatusCode == b.StatusCode &&
a.Reflections == b.Reflections &&
similarity >= threshold
}
func responsesAreEqual(a, b ResponseData) bool {
return a.StatusCode == b.StatusCode &&
a.Reflections == b.Reflections &&
a.BodyHash == b.BodyHash
}
func baselineResponsesAreConsistent(baselineResponses []ResponseData, compareFunc func(ResponseData, ResponseData) bool) bool {
for i := 0; i < len(baselineResponses); i++ {
for j := i + 1; j < len(baselineResponses); j++ {
if !compareFunc(baselineResponses[i], baselineResponses[j]) {
return false
}
}
}
return true
}
func computeSimilarity(aBody, bBody []byte) float64 {
aText := string(aBody)
bText := string(bBody)
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(aText, bText, false)
distance := dmp.DiffLevenshtein(diffs)
// Calculate the maximum possible distance
maxLen := len(aText)
if len(bText) > maxLen {
maxLen = len(bText)
}
if maxLen == 0 {
return 1.0 // Both strings are empty, so they are identical
}
// Compute similarity as (1 - (distance / maxLen))
similarity := 1 - float64(distance)/float64(maxLen)
return similarity
}