-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathequivalanceClassifier.rb
executable file
·125 lines (112 loc) · 2.9 KB
/
equivalanceClassifier.rb
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/ruby
#
# This class processes each line of input and retains state between commands.
#
class EquivalenceClassifier
def initialize
# Store pass/fail results - key = string size, value = result
@results = Hash.new
end
def getResults
return @results
end
def pass(value)
return passFail(value, "pass")
end
def fail(value, comment = nil)
return passFail(value, "fail", comment)
end
# Record test results. Overwrite a previous report for the same value if necessary.
def passFail(value, result, comment = nil)
if (value == nil)
raise "No counterstring to mark."
else
wholeLine = result
if (comment != nil && comment.length > 0)
wholeLine += " " + comment
end
if @results.has_key?(value)
puts value.to_s + " result changed from " + @results[value] + " to " + wholeLine
else
puts value.to_s + " recorded as " + wholeLine
end
@results[value] = wholeLine
end
end
def getResults
return @results
end
# Helper. Find a boundary between groups of identical test results. Different boundaries are numbered starting with "1".
def findBoundary(boundaryNum)
lower = nil
upper = nil
foundBoundary = 0
if boundaryNum < 1
raise "boundary number must be 1 or greater"
end
@results.keys.sort.each do |key|
if lower == nil
lower = key
else
if @results[key] == @results[lower]
lower = key
next
else
foundBoundary += 1
if foundBoundary == boundaryNum
upper = key
break
else
lower = key
end
end
end
end
return lower, upper, foundBoundary
end
# For a given boundary where behavior changes, do a bisection between them to zero in on where the transition occurs.
def bisect(boundary)
#if (! defined? boundary)
# boundary = 1
#end
if @results.length < 2
raise "can't bisect - need two different test results"
end
lower, upper, foundBoundary = findBoundary(boundary)
if boundary > foundBoundary
raise "Boundary '" + boundary.to_s + "' too high - there are only " + foundBoundary.to_s + " boundaries (see 'status')"
else
bisect = lower + ((upper - lower) / 2).to_i
highLow = "highest value for '" + @results[lower] + "': " + lower.to_s + "\n" +
"lowest value for '" + @results[upper] + "': " + upper.to_s
puts highLow
if @results.has_key?(bisect)
puts "Boundary found!"
return nil
else
return bisect
end
end
end
# Clear previously reported results
def reset
@results.clear
end
# Show all test results and the boundaries between group of different results ("pass", "fail", and each "fail <s>")
def status
if @results.empty?
puts "no status yet"
else
lastValue = nil
boundaries = 0
@results.keys.sort.each do |key|
if (lastValue != nil && @results[key] != lastValue)
boundaries += 1
puts "--boundary " + boundaries.to_s
end
lastValue = @results[key]
puts key.to_s + ": " + @results[key]
end
end
end
end