assert 2.15.2 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/lib/assert/assertions.rb +6 -0
  3. data/lib/assert/config_helpers.rb +35 -14
  4. data/lib/assert/context.rb +36 -43
  5. data/lib/assert/context/test_dsl.rb +4 -4
  6. data/lib/assert/default_suite.rb +35 -40
  7. data/lib/assert/default_view.rb +109 -37
  8. data/lib/assert/file_line.rb +1 -1
  9. data/lib/assert/result.rb +67 -27
  10. data/lib/assert/runner.rb +14 -10
  11. data/lib/assert/suite.rb +41 -50
  12. data/lib/assert/test.rb +39 -81
  13. data/lib/assert/version.rb +1 -1
  14. data/lib/assert/view_helpers.rb +11 -21
  15. data/test/helper.rb +40 -0
  16. data/test/system/test_tests.rb +90 -88
  17. data/test/unit/assertions/assert_block_tests.rb +14 -10
  18. data/test/unit/assertions/assert_empty_tests.rb +14 -10
  19. data/test/unit/assertions/assert_equal_tests.rb +22 -14
  20. data/test/unit/assertions/assert_file_exists_tests.rb +14 -10
  21. data/test/unit/assertions/assert_includes_tests.rb +14 -10
  22. data/test/unit/assertions/assert_instance_of_tests.rb +14 -10
  23. data/test/unit/assertions/assert_kind_of_tests.rb +14 -10
  24. data/test/unit/assertions/assert_match_tests.rb +14 -10
  25. data/test/unit/assertions/assert_nil_tests.rb +14 -10
  26. data/test/unit/assertions/assert_raises_tests.rb +14 -10
  27. data/test/unit/assertions/assert_respond_to_tests.rb +14 -10
  28. data/test/unit/assertions/assert_same_tests.rb +20 -14
  29. data/test/unit/assertions/assert_true_false_tests.rb +28 -20
  30. data/test/unit/assertions_tests.rb +12 -9
  31. data/test/unit/config_helpers_tests.rb +72 -13
  32. data/test/unit/context/test_dsl_tests.rb +38 -45
  33. data/test/unit/context_tests.rb +12 -8
  34. data/test/unit/default_suite_tests.rb +66 -43
  35. data/test/unit/file_line_tests.rb +4 -1
  36. data/test/unit/result_tests.rb +71 -47
  37. data/test/unit/runner_tests.rb +34 -16
  38. data/test/unit/suite_tests.rb +61 -29
  39. data/test/unit/test_tests.rb +97 -134
  40. data/test/unit/view_helpers_tests.rb +17 -31
  41. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA512:
3
- data.tar.gz: 87349e6848472856f049017257486230a2b69f52bcf4d5ebdf4d4a23f88dd5b479d1499890ea1c63e890186c4c86d665c982d162ebd86a51e07762b809029e26
4
- metadata.gz: 539e868afc215555b585a85dd4caf52e9fbc7082e2eada2c33aea41900e22bb3a547c193b40f5433192bcd27571efd79254d93f54b7a973eab8fef0489398a55
5
2
  SHA1:
6
- data.tar.gz: fd4a2030e5b99394b4461d7673324e00fad58647
7
- metadata.gz: bb7bf7dd4fb2b739e897932d9499487ac730e1fc
3
+ data.tar.gz: 05d9e740571423b4946bf4744e82d1c329635de5
4
+ metadata.gz: 059d25ec7c38612afd6e776156ca4e81459eafc7
5
+ SHA512:
6
+ data.tar.gz: 863376fa7090c85130e651358ddbe6a1c53e47de4d0c1698d51ca94ce665bb51f13ef2029909b6e4c6f84768fb5e4a0b606939c39642f8b4f64ee3e446585356
7
+ metadata.gz: c9dfcbdc44401730b6bf66f9adca789657d82911b784ed453a5f2b077717a98160334ddecf96bcc5198c999d556c3984b4e29a0037b09f6af0247442e8c015a0
@@ -264,6 +264,12 @@ module Assert
264
264
  end
265
265
  end
266
266
 
267
+ private
268
+
269
+ def __assert_config__
270
+ raise NotImplementedError # should be defined by the config mixing this in
271
+ end
272
+
267
273
  # exception raised utility classes
268
274
 
269
275
  class CheckException
@@ -18,28 +18,43 @@ module Assert
18
18
  self.config.single_test_file_line
19
19
  end
20
20
 
21
- def count(type)
22
- self.config.suite.count(type)
21
+ def tests_to_run?; self.config.suite.tests_to_run?; end
22
+ def tests_to_run_count; self.config.suite.tests_to_run_count; end
23
+
24
+ def test_count; self.config.suite.test_count; end
25
+ def result_count; self.config.suite.result_count; end
26
+ def pass_result_count; self.config.suite.pass_result_count; end
27
+ def fail_result_count; self.config.suite.fail_result_count; end
28
+ def error_result_count; self.config.suite.error_result_count; end
29
+ def skip_result_count; self.config.suite.skip_result_count; end
30
+ def ignore_result_count; self.config.suite.ignore_result_count; end
31
+
32
+ def all_pass?
33
+ self.pass_result_count == self.result_count
23
34
  end
24
35
 
25
- def tests?
26
- self.count(:tests) > 0
36
+ def formatted_run_time(run_time, format = '%.6f')
37
+ format % run_time
27
38
  end
28
39
 
29
- def all_pass?
30
- self.count(:pass) == self.count(:results)
40
+ def formatted_test_rate(test_rate, format = '%.6f')
41
+ format % test_rate
31
42
  end
32
43
 
33
- def formatted_run_time(format = '%.6f')
34
- format % self.config.suite.run_time
44
+ def formatted_result_rate(result_rate, format = '%.6f')
45
+ format % result_rate
35
46
  end
36
47
 
37
- def formatted_test_rate(format = '%.6f')
38
- format % self.config.suite.test_rate
48
+ def formatted_suite_run_time(format = '%.6f')
49
+ formatted_run_time(self.config.suite.run_time, format)
39
50
  end
40
51
 
41
- def formatted_result_rate(format = '%.6f')
42
- format % self.config.suite.result_rate
52
+ def formatted_suite_test_rate(format = '%.6f')
53
+ formatted_test_rate(self.config.suite.test_rate, format)
54
+ end
55
+
56
+ def formatted_suite_result_rate(format = '%.6f')
57
+ formatted_result_rate(self.config.suite.result_rate, format)
43
58
  end
44
59
 
45
60
  def show_test_profile_info?
@@ -50,13 +65,19 @@ module Assert
50
65
  !!self.config.verbose
51
66
  end
52
67
 
53
- # return a list of result symbols that have actually occurred
68
+ # return a list of result type symbols that have actually occurred
54
69
  def ocurring_result_types
55
70
  @result_types ||= [:pass, :fail, :ignore, :skip, :error].select do |sym|
56
- self.count(sym) > 0
71
+ self.send("#{sym}_result_count") > 0
57
72
  end
58
73
  end
59
74
 
75
+ private
76
+
77
+ def get_rate(count, time)
78
+ time == 0 ? 0.0 : (count.to_f / time.to_f)
79
+ end
80
+
60
81
  end
61
82
 
62
83
  end
@@ -39,22 +39,28 @@ module Assert
39
39
  self.suite.test_methods << klass_method_name
40
40
  end
41
41
 
42
- self.suite.tests << Test.for_method(
42
+ self.suite.on_test(Test.for_method(
43
43
  method_name.to_s,
44
44
  ContextInfo.new(self, nil, caller.first),
45
45
  self.suite.config
46
- )
46
+ ))
47
47
  end
48
48
  end
49
49
 
50
50
  def initialize(running_test, config, result_callback)
51
- @__running_test__ = running_test
52
- @__assert_config__ = config
53
- @__result_callback__ = result_callback
51
+ @__assert_running_test__ = running_test
52
+ @__assert_config__ = config
53
+ @__assert_with_bt__ = nil
54
+
55
+ @__assert_result_callback__ = proc do |result|
56
+ result.set_backtrace(@__assert_with_bt__) if @__assert_with_bt__
57
+ result_callback.call(result)
58
+ result
59
+ end
54
60
  end
55
61
 
56
- # check if the assertion is a truthy value, if so create a new pass result, otherwise
57
- # create a new fail result with the desc and what failed msg.
62
+ # check if the assertion is a truthy value, if so create a new pass result,
63
+ # otherwise create a new fail result with the desc and what failed msg.
58
64
  # all other assertion helpers use this one in the end
59
65
  def assert(assertion, desc = nil)
60
66
  if assertion
@@ -63,7 +69,8 @@ module Assert
63
69
  what = if block_given?
64
70
  yield
65
71
  else
66
- "Failed assert: assertion was `#{Assert::U.show(assertion, __assert_config__)}`."
72
+ "Failed assert: assertion was "\
73
+ "`#{Assert::U.show(assertion, __assert_config__)}`."
67
74
  end
68
75
  fail(fail_message(desc, what))
69
76
  end
@@ -73,7 +80,8 @@ module Assert
73
80
  # result, otherwise create a new fail result with the desc and it's what failed msg
74
81
  def assert_not(assertion, fail_desc = nil)
75
82
  assert(!assertion, fail_desc) do
76
- "Failed assert_not: assertion was `#{Assert::U.show(assertion, __assert_config__)}`."
83
+ "Failed assert_not: assertion was "\
84
+ "`#{Assert::U.show(assertion, __assert_config__)}`."
77
85
  end
78
86
  end
79
87
  alias_method :refute, :assert_not
@@ -81,17 +89,13 @@ module Assert
81
89
  # adds a Pass result to the end of the test's results
82
90
  # does not break test execution
83
91
  def pass(pass_msg = nil)
84
- capture_result do |test, backtrace|
85
- Assert::Result::Pass.for_test(test, pass_msg, backtrace)
86
- end
92
+ capture_result(Assert::Result::Pass, pass_msg)
87
93
  end
88
94
 
89
95
  # adds an Ignore result to the end of the test's results
90
96
  # does not break test execution
91
97
  def ignore(ignore_msg = nil)
92
- capture_result do |test, backtrace|
93
- Assert::Result::Ignore.for_test(test, ignore_msg, backtrace)
94
- end
98
+ capture_result(Assert::Result::Ignore, ignore_msg)
95
99
  end
96
100
 
97
101
  # adds a Fail result to the end of the test's results
@@ -100,31 +104,29 @@ module Assert
100
104
  if halt_on_fail?
101
105
  raise Result::TestFailure, message || ''
102
106
  else
103
- capture_result do |test, backtrace|
104
- Assert::Result::Fail.for_test(test, message || '', backtrace)
105
- end
107
+ capture_result(Assert::Result::Fail, message || '')
106
108
  end
107
109
  end
108
110
  alias_method :flunk, :fail
109
111
 
110
- # adds a Skip result to the end of the test's results and breaks test execution
112
+ # adds a Skip result to the end of the test's results
113
+ # breaks test execution
111
114
  def skip(skip_msg = nil, called_from = nil)
112
115
  err = Result::TestSkipped.new(skip_msg || '')
113
116
  err.set_backtrace([called_from]) if called_from
114
117
  raise(err)
115
118
  end
116
119
 
117
- # alter the backtraces of fail results generated in the given block
120
+ # alter the backtraces of fail/skip results generated in the given block
118
121
  def with_backtrace(bt, &block)
119
122
  bt ||= []
120
- current_results.size.tap do |size|
121
- begin
122
- instance_eval(&block)
123
- rescue Result::TestSkipped, Result::TestFailure => e
124
- e.set_backtrace(bt); raise(e)
125
- ensure
126
- current_results[size..-1].each{ |r| r.set_backtrace(bt) }
127
- end
123
+ begin
124
+ @__assert_with_bt__ = bt
125
+ instance_eval(&block)
126
+ rescue Result::TestSkipped, Result::TestFailure => e
127
+ e.set_backtrace(@__assert_with_bt__); raise(e)
128
+ ensure
129
+ @__assert_with_bt__ = nil
128
130
  end
129
131
  end
130
132
 
@@ -140,7 +142,8 @@ module Assert
140
142
 
141
143
  protected
142
144
 
143
- # Returns a Proc that will output a custom message along with the default fail message.
145
+ # Returns a Proc that will output a custom message along with the default
146
+ # fail message.
144
147
  def fail_message(fail_desc = nil, what_failed_msg = nil)
145
148
  [ fail_desc, what_failed_msg ].compact.join("\n")
146
149
  end
@@ -151,20 +154,10 @@ module Assert
151
154
  __assert_config__.halt_on_fail
152
155
  end
153
156
 
154
- def capture_result
155
- if block_given?
156
- result = yield __running_test__, caller
157
- __running_test__.capture_result(result, @__result_callback__)
158
- result
159
- end
160
- end
161
-
162
- def current_results
163
- __running_test__.results
164
- end
165
-
166
- def __running_test__
167
- @__running_test__
157
+ def capture_result(result_klass, msg)
158
+ @__assert_result_callback__.call(
159
+ result_klass.for_test(@__assert_running_test__, msg, caller)
160
+ )
168
161
  end
169
162
 
170
163
  def __assert_config__
@@ -13,12 +13,12 @@ class Assert::Context
13
13
  instance_eval(&desc_or_macro)
14
14
  elsif block_given?
15
15
  # create a test from the given code block
16
- self.suite.tests << Assert::Test.for_block(
16
+ self.suite.on_test(Assert::Test.for_block(
17
17
  desc_or_macro.kind_of?(Assert::Macro) ? desc_or_macro.name : desc_or_macro,
18
18
  Assert::ContextInfo.new(self, called_from, first_caller || caller.first),
19
19
  self.suite.config,
20
20
  &block
21
- )
21
+ ))
22
22
  else
23
23
  test_eventually(desc_or_macro, called_from, first_caller || caller.first, &block)
24
24
  end
@@ -27,12 +27,12 @@ class Assert::Context
27
27
  def test_eventually(desc_or_macro, called_from = nil, first_caller = nil, &block)
28
28
  # create a test from a proc that just skips
29
29
  ci = Assert::ContextInfo.new(self, called_from, first_caller || caller.first)
30
- self.suite.tests << Assert::Test.for_block(
30
+ self.suite.on_test(Assert::Test.for_block(
31
31
  desc_or_macro.kind_of?(Assert::Macro) ? desc_or_macro.name : desc_or_macro,
32
32
  ci,
33
33
  self.suite.config,
34
34
  &proc { skip('TODO', ci.called_from) }
35
- )
35
+ ))
36
36
  end
37
37
  alias_method :test_skip, :test_eventually
38
38
 
@@ -2,63 +2,58 @@ require 'assert/suite'
2
2
 
3
3
  module Assert
4
4
 
5
- # This is the default suite used by assert. It stores test/result data in-memory.
5
+ # This is the default suite used by assert. In addition to the base suite
6
+ # behavior, it accumulates test/result counts in memory. This data is used
7
+ # by the runner/view for handling and presentation purposes.
6
8
 
7
9
  class DefaultSuite < Assert::Suite
8
10
 
9
- # Test data
10
-
11
- def ordered_tests
12
- self.tests
13
- end
14
-
15
- def reversed_tests
16
- self.tests.reverse
11
+ def initialize(config)
12
+ super
13
+ reset_run_data
17
14
  end
18
15
 
19
- def ordered_tests_by_run_time
20
- self.ordered_tests.sort{ |a, b| a.run_time <=> b.run_time }
21
- end
16
+ def test_count; @test_count; end
17
+ def result_count; @result_count; end
18
+ def pass_result_count; @pass_result_count; end
19
+ def fail_result_count; @fail_result_count; end
20
+ def error_result_count; @error_result_count; end
21
+ def skip_result_count; @skip_result_count; end
22
+ def ignore_result_count; @ignore_result_count; end
22
23
 
23
- def reversed_tests_by_run_time
24
- self.ordered_tests_by_run_time.reverse
25
- end
24
+ # Callbacks
26
25
 
27
- def test_count
28
- self.tests.size
26
+ def on_start
27
+ reset_run_data
29
28
  end
30
29
 
31
- # Result data
32
-
33
- def ordered_results
34
- self.ordered_tests.inject([]){ |results, test| results += test.results }
30
+ def before_test(test)
31
+ @test_count += 1
35
32
  end
36
33
 
37
- def reversed_results
38
- self.ordered_results.reverse
34
+ def on_result(result)
35
+ @result_count += 1
36
+ self.send("increment_#{result.type}_result_count")
39
37
  end
40
38
 
41
- # dump failed or errored results,
42
- # dump skipped or ignored results if they have a message
43
- def ordered_results_for_dump
44
- self.ordered_results.select do |result|
45
- [:fail, :error].include?(result.to_sym) ||
46
- !!([:skip, :ignore].include?(result.to_sym) && result.message)
47
- end
48
- end
39
+ private
49
40
 
50
- def reversed_results_for_dump
51
- self.ordered_results_for_dump.reverse
52
- end
41
+ def increment_pass_result_count; @pass_result_count += 1; end
42
+ def increment_fail_result_count; @fail_result_count += 1; end
43
+ def increment_error_result_count; @error_result_count += 1; end
44
+ def increment_skip_result_count; @skip_result_count += 1; end
45
+ def increment_ignore_result_count; @ignore_result_count += 1; end
53
46
 
54
- def result_count(type = nil)
55
- self.tests.inject(0){ |count, test| count += test.result_count(type) }
47
+ def reset_run_data
48
+ @test_count = 0
49
+ @result_count = 0
50
+ @pass_result_count = 0
51
+ @fail_result_count = 0
52
+ @error_result_count = 0
53
+ @skip_result_count = 0
54
+ @ignore_result_count = 0
56
55
  end
57
56
 
58
- # Callbacks
59
-
60
- # no custom callbacks
61
-
62
57
  end
63
58
 
64
59
  end
@@ -22,58 +22,41 @@ module Assert
22
22
  end
23
23
 
24
24
  def after_load
25
- puts "Loaded suite (#{test_count_statement})"
25
+ puts "Loaded suite (#{tests_to_run_count_statement})"
26
26
  end
27
27
 
28
28
  def on_start
29
- end
30
-
31
- def before_test(test)
32
- if show_test_verbose_info?
33
- puts "#{test.name.inspect} (#{test.context_class})"
34
- puts " #{test.file_line}"
35
- print " "
36
- end
37
- end
38
-
39
- def on_result(result)
40
- print ansi_styled_msg(self.send("#{result.to_sym}_abbrev"), result)
41
- end
42
-
43
- def after_test(test)
44
- if show_test_verbose_info?
45
- print " #{test_run_time(test)} seconds,"\
46
- " #{test.result_count} results,"\
47
- " #{test_result_rate(test)} results/s\n"
48
- end
29
+ reset_run_data
30
+ set_callbacks
49
31
  end
50
32
 
51
33
  def on_finish
52
- if tests?
34
+ if self.test_count > 0
53
35
  dump_test_results
54
36
  end
55
37
 
56
38
  # show profile output
57
39
  if show_test_profile_info?
58
- config.suite.ordered_tests_by_run_time.each do |test|
59
- puts "#{test_run_time(test)} seconds,"\
60
- " #{test.result_count} results,"\
61
- " #{test_result_rate(test)} results/s --"\
62
- " #{test.context_class}: #{test.name.inspect}"
40
+ # sort the test datas fastest to slowest
41
+ @test_datas.values.sort{ |a, b| a.run_time <=> b.run_time }.each do |test_data|
42
+ puts "#{formatted_run_time(test_data.run_time)} seconds,"\
43
+ " #{test_data.result_count} results,"\
44
+ " #{formatted_result_rate(test_data.result_rate)} results/s --"\
45
+ " #{test_data.context}: #{test_data.name.inspect}"
63
46
  end
64
47
  puts
65
48
  end
66
49
 
67
50
  # style the summaries of each result set
68
- styled_results_sentence = results_summary_sentence do |summary, result_sym|
69
- ansi_styled_msg(summary, result_sym)
51
+ styled_results_sentence = results_summary_sentence do |summary, result_type|
52
+ ansi_styled_msg(summary, result_type)
70
53
  end
71
54
 
72
55
  puts "#{result_count_statement}: #{styled_results_sentence}"
73
56
  puts
74
- puts "(#{formatted_run_time} seconds, " \
75
- "#{formatted_test_rate} tests/s, " \
76
- "#{formatted_result_rate} results/s)"
57
+ puts "(#{formatted_suite_run_time} seconds, " \
58
+ "#{formatted_suite_test_rate} tests/s, " \
59
+ "#{formatted_suite_result_rate} results/s)"
77
60
  end
78
61
 
79
62
  def on_interrupt(err)
@@ -82,24 +65,113 @@ module Assert
82
65
 
83
66
  private
84
67
 
68
+ def reset_run_data
69
+ @results_to_dump = []
70
+ @test_datas = {}
71
+ end
72
+
73
+ def set_callbacks
74
+ @metaclass = class << self; self; end
75
+ if accumulate_test_data?
76
+ @metaclass.class_eval <<-callbacks
77
+ def before_test(test)
78
+ test_data = get_test_data(test)
79
+ puts "\#{test_data.name.inspect} (\#{test_data.context})"
80
+ puts " \#{test_data.file_line}"
81
+ print " "
82
+ end
83
+
84
+ def on_result(result)
85
+ print ansi_styled_msg(self.send("\#{result.to_sym}_abbrev"), result.type)
86
+ @results_to_dump << ResultData.for_result(result) if dumpable_result?(result)
87
+ find_test_data(result.test_file_line).result_count += 1
88
+ end
89
+
90
+ def after_test(test)
91
+ test_data = find_test_data(test.file_line)
92
+ test_data.run_time = test.run_time
93
+ test_data.result_rate = get_rate(test_data.result_count, test_data.run_time)
94
+
95
+ if show_test_verbose_info?
96
+ print " \#{formatted_run_time(test_data.run_time)} seconds,"\
97
+ " \#{test_data.result_count} results,"\
98
+ " \#{formatted_result_rate(test_data.result_rate)} results/s\n"
99
+ end
100
+ end
101
+ callbacks
102
+ else
103
+ @metaclass.class_eval <<-callbacks
104
+ def on_result(result)
105
+ print ansi_styled_msg(self.send("\#{result.to_sym}_abbrev"), result.type)
106
+ @results_to_dump << ResultData.for_result(result) if dumpable_result?(result)
107
+ end
108
+ callbacks
109
+ end
110
+ end
111
+
112
+ def accumulate_test_data?
113
+ show_test_verbose_info? || show_test_profile_info?
114
+ end
115
+
116
+ def get_test_data(test)
117
+ @test_datas[test.file_line.to_s] ||= TestData.for_test(test)
118
+ end
119
+
120
+ def find_test_data(test_file_line)
121
+ @test_datas[test_file_line.to_s]
122
+ end
123
+
124
+ def dumpable_result?(result)
125
+ [:fail, :error].include?(result.type) ||
126
+ !!([:skip, :ignore].include?(result.type) && result.message)
127
+ end
128
+
85
129
  def dump_test_results
86
130
  print "\n"
87
131
  puts
88
132
 
89
- config.suite.reversed_results_for_dump.each do |result|
133
+ @results_to_dump.sort.each do |result_data|
90
134
  # output the styled result details
91
- puts ansi_styled_msg(result.to_s, result)
135
+ puts ansi_styled_msg(result_data.details, result_data.type)
92
136
 
93
137
  # output any captured stdout
94
- puts captured_output(result.output) if result.output && !result.output.empty?
138
+ if result_data.output && !result_data.output.empty?
139
+ puts captured_output(result_data.output)
140
+ end
95
141
 
96
142
  # output re-run CLI cmd
97
- puts re_run_test_cmd(result.test_id)
143
+ puts re_run_test_cmd(result_data.test_id)
98
144
 
99
- # add an empty line between each result detail
145
+ # add an empty line between each dumped result
100
146
  puts
101
147
  end
148
+ end
149
+
150
+ attrs = [:name, :context, :file_line, :result_count, :run_time, :result_rate]
151
+ class TestData < Struct.new(*attrs)
152
+ def self.for_test(t)
153
+ self.new(t.name, t.context_class, t.file_line.to_s, 0, 0.0, 0.0)
154
+ end
155
+ end
156
+
157
+ attrs = [:type, :details, :output, :test_id, :sort_by]
158
+ class ResultData < Struct.new(*attrs)
159
+ def self.for_result(r)
160
+ self.new(r.type, r.to_s, r.output, r.test_id, self.sort_by(r))
161
+ end
102
162
 
163
+ def self.sort_by(r)
164
+ [r.test_file_name, r.test_line_num, r.file_name, r.line_num]
165
+ end
166
+
167
+ def <=>(other_rd)
168
+ # show in reverse definition order
169
+ if other_rd.kind_of?(ResultData)
170
+ other_rd.sort_by <=> self.sort_by
171
+ else
172
+ super
173
+ end
174
+ end
103
175
  end
104
176
 
105
177
  end