probatio 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f855685ad365c5dfbaa6c719b930f0b5113d35ab47cee5e31dff2c9af994b1f7
4
- data.tar.gz: be76c4d06ec56b0541bf256b87fede46a30d455bba1c2b55192ebfd3da9fa8e9
3
+ metadata.gz: 5935c5e5ed80703f327b9080a0853dec130b1e5b595f29a5ee914a493865368b
4
+ data.tar.gz: 37167cd9088927754eddc83b2f75a765be851c6e6c2b602e1f77d6c1c60b681e
5
5
  SHA512:
6
- metadata.gz: 3192dc95ac4aa5c09e965f25207331ebb8801607c92e9c72fbc6373644be62a2a961ddfce26cdbfc50969aed3e2640b461427ee23896e8c236d946b3908a99a8
7
- data.tar.gz: 8fb9d38e3a4111d2d968b4a54deb10ce997ac9ea1dd16127d99289ab71789ca825e768d01c770d07e6b23c00fd0945fe80fbe5ce47f3bf97a05cc5cea2718567
6
+ metadata.gz: d3ac2a8013890f1b9d05bf2b836e2360081082a99135173976685c6cd7d4bac74534771c2d4e7d4e358577632b97377a8998e2c4715386b6e9b0da20f743c10b
7
+ data.tar.gz: e0e7595dd5163fa4c43f574dea4af27eb03ea684ed10ed54c6f50ceaecd2db81dc6c328b409ff80374419f94cf5b3d6fd308caf1928c2ab5eadd982e25f65ece
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ## probatio 1.4.0 released 2025-10-13
6
+
7
+ * Work on StringDiff, HashDiff, and ArrayDiff
8
+ * Use diff-lcs for StringDiff
9
+
10
+
5
11
  ## probatio 1.3.0 released 2025-08-08
6
12
 
7
13
  * Add windows? and jruby? to Probatio::Group
@@ -0,0 +1,279 @@
1
+
2
+ #
3
+ # probatio/errors.rb
4
+
5
+ module Probatio
6
+
7
+ class AssertionError < StandardError
8
+
9
+ attr_reader :assertion, :arguments, :test, :file, :line
10
+ attr_accessor :nested_error
11
+
12
+ alias path file
13
+
14
+ def initialize(assertion, arguments, error_or_message, test, file, line)
15
+
16
+ @assertion = assertion
17
+ @arguments = arguments
18
+
19
+ @test = test
20
+
21
+ @file = file
22
+ @line = line
23
+
24
+ if error_or_message.is_a?(String)
25
+ @msg = error_or_message
26
+ else
27
+ @msg = "error while asserting: " + error_or_message.message
28
+ @nested_error = error_or_message
29
+ end
30
+
31
+ super(@msg)
32
+ end
33
+
34
+ def location
35
+
36
+ [ @file, @line ]
37
+ end
38
+
39
+ def loc
40
+
41
+ location.map(&:to_s).join(':')
42
+ end
43
+
44
+ def to_s
45
+
46
+ "#{self.class.name}: #{@msg}"
47
+ end
48
+
49
+ def trail
50
+
51
+ @test.trail + "\n" +
52
+ Probatio.c.red("#{' ' * (test.depth + 1)}#{loc} --> #{@msg}")
53
+ end
54
+
55
+ def source_line
56
+
57
+ @source_line ||=
58
+ File.readlines(@file)[@line - 1]
59
+ end
60
+
61
+ def source_lines
62
+
63
+ @source_lines ||=
64
+ Probatio::AssertionError.select_source_lines(@file, @line)
65
+ end
66
+
67
+ def summary(indent='')
68
+
69
+ nl = "\n" + indent
70
+
71
+ tw = Probatio.term_width - 4 - indent.length
72
+
73
+ as =
74
+ @arguments.find { |a| a.inspect.length > tw } ?
75
+ @arguments.collect { |a|
76
+ if (s0 = a.inspect).length < tw
77
+ nl + ' ' + s0 + "\n"
78
+ else
79
+ s1 = StringIO.new; PP.pp(a, s1, tw)
80
+ qualify_argument(a) + "\n" +
81
+ indent + s1.string.gsub(/^(.*)$/) { " #{$1}" }
82
+ end } :
83
+ @arguments.collect(&:inspect)
84
+
85
+ s = StringIO.new
86
+ s << indent << @assertion << ':'
87
+
88
+ case @arguments.collect(&:class)
89
+ when [ Hash, Hash ]
90
+ as.each_with_index { |a, i| s << nl << ' %d: %s' % [ i, a ] }
91
+ output_hash_diff(indent, s)
92
+ when [ Array, Array ]
93
+ output_array_diff(indent, s)
94
+ when [ String, String ]
95
+ output_string_diff(indent, s)
96
+ else
97
+ as.each_with_index { |a, i| s << nl << ' %d: %s' % [ i, a ] }
98
+ end
99
+
100
+ s.string
101
+ end
102
+
103
+ class << self
104
+
105
+ def select_source_lines(path, line)
106
+
107
+ return [] unless path
108
+
109
+ File.readlines(path).each_with_index.to_a[line - 1..-1]
110
+ .map { |l, i| [ i + 1, l.rstrip ] }
111
+ .take_while { |_, l|
112
+ l = l.strip
113
+ l.length > 0 && l != 'end' && l != '}' }
114
+ end
115
+ end
116
+
117
+ protected
118
+
119
+ def output_hash_diff(indent, s)
120
+
121
+ nl = "\n" + indent
122
+
123
+ c = Probatio.c
124
+
125
+ d0 = @arguments[0].to_a - @arguments[1].to_a
126
+ d1 = @arguments[1].to_a - @arguments[0].to_a
127
+
128
+ dh = {}
129
+ d0.each { |k, v| dh[k] = [ v, nil ] }
130
+ d1.each { |k, v| dv = (dh[k] ||= [ nil, nil ]); dv[1] = v }
131
+
132
+ s << nl << ' Hash diff:'
133
+ dh.each do |k, (v0, v1)|
134
+ s << nl << ' ' << c.yellow(k.inspect) << c.dg << ' =>'
135
+ s << nl << ' ' << c.white(0) << c.dg << ': ' << v0.inspect
136
+ s << " -- has_key? #{@arguments[0].has_key?(k)}" if v0 == nil
137
+ s << nl << ' ' << c.white(1) << c.dg << ': ' << v1.inspect
138
+ s << " -- has_key? #{@arguments[1].has_key?(k)}" if v1 == nil
139
+ end
140
+ end
141
+
142
+ def output_string_diff(indent, s)
143
+
144
+ a0, a1 = @arguments
145
+ a0l, a1l = a0.length, a1.length
146
+ a0c, a1c = a0.lines.count, a1.lines.count
147
+
148
+ sep = "\n" + ('-' * 49)
149
+ c = Probatio.c
150
+
151
+ s <<
152
+ sep << " length: #{a0l} / lines: #{a0c}\n" <<
153
+ c.yellow << a0 << c.dark_grey <<
154
+ sep << " length: #{a1l} / lines: #{a1c}\n" <<
155
+ c.yellow << a1 << c.dark_grey <<
156
+ sep
157
+
158
+ ls0 = @arguments[0].lines.map(&:chomp)
159
+ ls1 = @arguments[1].lines.map(&:chomp)
160
+
161
+ return if ls0.length < 2 && ls1.length < 2
162
+
163
+ output_sdiff(ls0, ls1, s)
164
+ end
165
+
166
+ def output_array_diff(indent, s)
167
+
168
+ a0, a1 = @arguments
169
+ a0c, a1c = a0.count, a1.count
170
+
171
+ sep = "\n" + ('-' * 49)
172
+ c = Probatio.c
173
+
174
+ s << c.dg << sep << "length: #{a0c}\n" << c.white << a0.inspect
175
+ s << c.dg << sep << "length: #{a1c}\n" << c.white << a1.inspect
176
+ s << c.dg << sep
177
+
178
+ s0 = a0.collect { |e| e.is_a?(String) ? e : e.inspect }
179
+ s1 = a1.collect { |e| e.is_a?(String) ? e : e.inspect }
180
+
181
+ output_sdiff(s0, s1, s)
182
+ end
183
+
184
+ def output_sdiff(a0, a1, s)
185
+
186
+ c = Probatio.c
187
+ nl = "\n"
188
+ sep = "\n" + ('-' * 49)
189
+
190
+ diff = Diff::LCS.sdiff(a0, a1).collect(&:to_a)
191
+
192
+ maxl = diff
193
+ .inject([]) { |a, d| a << d[1][0]; a << d[2][0]; a }
194
+ .max.to_s.length
195
+ forl = "%0#{maxl}d"
196
+
197
+ #ov = c.rev(' ')
198
+ ov = c.dg + c.rev('<')
199
+ fence = lambda { |s| s + (s.match?(/\s$/) ? ov : '') }
200
+
201
+ s << nl << c.dg << sep
202
+ diff.each do |d|
203
+ if d[0] == '='
204
+ s << nl << c.dg << '= ' << (forl % d[1][0]) << ' ' << d[1][1]
205
+ elsif d[0] == '+'
206
+ #s << nl << d.inspect
207
+ s << nl << c.gn << '+ ' << (forl % d[2][0]) << ' ' << fence[d[2][1]]
208
+ elsif d[0] == '-'
209
+ #s << nl << d.inspect
210
+ s << nl << c.rd << '- ' << (forl % d[1][0]) << ' ' << fence[d[1][1]]
211
+ else # '!'
212
+ a, b = d[1], d[2]
213
+ s << nl << c.y << '! ' << (forl % a[0]) << ' ' << fence[a[1]]
214
+ s << nl << c.y << ' ' << (forl % b[0]) << ' ' << fence[b[1]]
215
+ end
216
+ end
217
+ s << c.dg << sep << c.reset
218
+ end
219
+
220
+ def qualify_argument(a)
221
+
222
+ '<' +
223
+ a.class.to_s +
224
+ (a.respond_to?(:size) ? " size:#{a.size}" : '') +
225
+ '>'
226
+ end
227
+ end
228
+
229
+ module ExtraErrorMethods
230
+
231
+ attr_accessor :test
232
+
233
+ def path; test.path; end
234
+ def location; [ path, line ]; end
235
+ def loc; location.map(&:to_s).join(':'); end
236
+
237
+ def trail
238
+
239
+ msg = "#{self.class}: #{self.message.inspect}"
240
+
241
+ @test.trail + "\n" +
242
+ Probatio.c.red("#{' ' * (test.depth + 1)}#{loc} --> #{msg}")
243
+ end
244
+
245
+ def source_lines
246
+
247
+ @source_lines ||=
248
+ Probatio::AssertionError.select_source_lines(test.path, line)
249
+ end
250
+
251
+ def summary(indent='')
252
+
253
+ o = StringIO.new
254
+
255
+ o << self.class.name << ': ' << self.message.inspect << "\n"
256
+
257
+ i = backtrace.index { |l| l.match?(/\/lib\/probatio\.rb:/) } || -1
258
+
259
+ backtrace[0..i]
260
+ .inject(o) { |o, l| o << indent << l << "\n" }
261
+
262
+ o.string
263
+ end
264
+
265
+ def line
266
+
267
+ backtrace.each do |l|
268
+
269
+ ss = l.split(':')
270
+
271
+ next unless ss.find { |e| e == test.path }
272
+ return ss.find { |e| e.match?(/^\d+$/) }.to_i
273
+ end
274
+
275
+ -1
276
+ end
277
+ end
278
+ end
279
+
data/lib/probatio.rb CHANGED
@@ -7,15 +7,18 @@ require 'set'
7
7
  require 'stringio'
8
8
  require 'io/console'
9
9
 
10
+ require 'diff-lcs'
11
+
10
12
  require 'colorato'
11
13
 
12
14
  require 'probatio/debug'
15
+ require 'probatio/errors'
13
16
  require 'probatio/more'
14
17
 
15
18
 
16
19
  module Probatio
17
20
 
18
- VERSION = '1.3.0'
21
+ VERSION = '1.4.0'
19
22
 
20
23
  class << self
21
24
 
@@ -758,164 +761,6 @@ module Probatio
758
761
  # where beep and friends are defined...
759
762
  end
760
763
 
761
- class AssertionError < StandardError
762
-
763
- attr_reader :assertion, :arguments, :test, :file, :line
764
- attr_accessor :nested_error
765
-
766
- alias path file
767
-
768
- def initialize(assertion, arguments, error_or_message, test, file, line)
769
-
770
- @assertion = assertion
771
- @arguments = arguments
772
-
773
- @test = test
774
-
775
- @file = file
776
- @line = line
777
-
778
- if error_or_message.is_a?(String)
779
- @msg = error_or_message
780
- else
781
- @msg = "error while asserting: " + error_or_message.message
782
- @nested_error = error_or_message
783
- end
784
-
785
- super(@msg)
786
- end
787
-
788
- def location
789
-
790
- [ @file, @line ]
791
- end
792
-
793
- def loc
794
-
795
- location.map(&:to_s).join(':')
796
- end
797
-
798
- def to_s
799
-
800
- "#{self.class.name}: #{@msg}"
801
- end
802
-
803
- def trail
804
-
805
- @test.trail + "\n" +
806
- Probatio.c.red("#{' ' * (test.depth + 1)}#{loc} --> #{@msg}")
807
- end
808
-
809
- def source_line
810
-
811
- @source_line ||=
812
- File.readlines(@file)[@line - 1]
813
- end
814
-
815
- def source_lines
816
-
817
- @source_lines ||=
818
- Probatio::AssertionError.select_source_lines(@file, @line)
819
- end
820
-
821
- def summary(indent='')
822
-
823
- tw = Probatio.term_width - 4 - indent.length
824
-
825
- as =
826
- @arguments.find { |a| a.inspect.length > tw } ?
827
- @arguments.collect { |a|
828
- if (s0 = a.inspect).length < tw
829
- "\n#{indent} " + s0
830
- else
831
- s1 = StringIO.new; PP.pp(a, s1, tw)
832
- qualify_argument(a) + "\n" +
833
- indent + s1.string.gsub(/^(.*)$/) { " #{$1}" }
834
- end } :
835
- @arguments.collect(&:inspect)
836
-
837
- s = StringIO.new
838
- s << indent << @assertion << ':'
839
- as.each_with_index { |a, i| s << "\n#{indent} %d: %s" % [ i, a ] }
840
-
841
- s.string
842
- end
843
-
844
- class << self
845
-
846
- def select_source_lines(path, line)
847
-
848
- return [] unless path
849
-
850
- File.readlines(path).each_with_index.to_a[line - 1..-1]
851
- .map { |l, i| [ i + 1, l.rstrip ] }
852
- .take_while { |_, l|
853
- l = l.strip
854
- l.length > 0 && l != 'end' && l != '}' }
855
- end
856
- end
857
-
858
- protected
859
-
860
- def qualify_argument(a)
861
-
862
- '<' +
863
- a.class.to_s +
864
- (a.respond_to?(:size) ? " size:#{a.size}" : '') +
865
- '>'
866
- end
867
- end
868
-
869
- module ExtraErrorMethods
870
-
871
- attr_accessor :test
872
-
873
- def path; test.path; end
874
- def location; [ path, line ]; end
875
- def loc; location.map(&:to_s).join(':'); end
876
-
877
- def trail
878
-
879
- msg = "#{self.class}: #{self.message.inspect}"
880
-
881
- @test.trail + "\n" +
882
- Probatio.c.red("#{' ' * (test.depth + 1)}#{loc} --> #{msg}")
883
- end
884
-
885
- def source_lines
886
-
887
- @source_lines ||=
888
- Probatio::AssertionError.select_source_lines(test.path, line)
889
- end
890
-
891
- def summary(indent='')
892
-
893
- o = StringIO.new
894
-
895
- o << self.class.name << ': ' << self.message.inspect << "\n"
896
-
897
- i = backtrace.index { |l| l.match?(/\/lib\/probatio\.rb:/) } || -1
898
-
899
- backtrace[0..i]
900
- .inject(o) { |o, l| o << indent << l << "\n" }
901
-
902
- o.string
903
- end
904
-
905
- def line
906
-
907
- backtrace.each do |l|
908
-
909
- ss = l.split(':')
910
-
911
- next unless ss.find { |e| e == test.path }
912
- return ss.find { |e| e.match?(/^\d+$/) }.to_i
913
- end
914
-
915
- -1
916
- end
917
- end
918
-
919
764
  class Event
920
765
 
921
766
  attr_reader :tstamp, :delta
data/probatio.gemspec CHANGED
@@ -38,8 +38,9 @@ Test tools for floraison and flor. Somewhere between Minitest and Rspec, but not
38
38
  "#{s.name}.gemspec",
39
39
  ]
40
40
 
41
+ s.add_runtime_dependency 'stringio'
42
+ s.add_runtime_dependency 'diff-lcs', '~> 1.6'
41
43
  s.add_runtime_dependency 'colorato', '~> 1.0'
42
- #s.add_runtime_dependency 'diff-lcs', '~> 1.5'
43
44
 
44
45
  s.require_path = 'lib'
45
46
 
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: probatio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-08 00:00:00.000000000 Z
11
+ date: 2025-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: stringio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: diff-lcs
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: colorato
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -40,6 +68,7 @@ files:
40
68
  - lib/probatio.rb
41
69
  - lib/probatio/assertions.rb
42
70
  - lib/probatio/debug.rb
71
+ - lib/probatio/errors.rb
43
72
  - lib/probatio/examples/a_plugin.rb
44
73
  - lib/probatio/examples/a_test.rb
45
74
  - lib/probatio/helpers.rb