activegroonga 0.0.7 → 1.0.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.
- data/README.ja.rdoc +4 -1
- data/README.rdoc +4 -1
- data/Rakefile +18 -4
- data/lib/active_groonga.rb +25 -52
- data/lib/active_groonga/base.rb +164 -1480
- data/lib/active_groonga/callbacks.rb +26 -7
- data/lib/active_groonga/database.rb +55 -0
- data/lib/active_groonga/{dirty.rb → error.rb} +20 -10
- data/lib/active_groonga/locale/en.yml +5 -0
- data/lib/active_groonga/migration.rb +44 -113
- data/lib/active_groonga/migrator.rb +172 -0
- data/lib/active_groonga/persistence.rb +172 -0
- data/lib/active_groonga/railtie.rb +66 -0
- data/lib/active_groonga/railties/configurable.rb +47 -0
- data/lib/active_groonga/railties/groonga.rake +167 -0
- data/lib/active_groonga/result_set.rb +89 -0
- data/lib/active_groonga/schema.rb +54 -188
- data/lib/active_groonga/validations.rb +54 -5
- data/lib/active_groonga/vector.rb +64 -0
- data/lib/active_groonga/version.rb +3 -3
- data/lib/{active_groonga/aggregations.rb → rails/generators/active_groonga.rb} +17 -10
- data/lib/rails/generators/active_groonga/migration/column.rb +101 -0
- data/lib/rails/generators/active_groonga/migration/migration_generator.rb +53 -0
- data/lib/rails/generators/active_groonga/migration/templates/migration.rb +29 -0
- data/lib/rails/generators/active_groonga/model/model_generator.rb +60 -0
- data/lib/rails/generators/active_groonga/model/templates/migration.rb +16 -0
- data/lib/rails/generators/active_groonga/model/templates/model.rb +2 -0
- data/lib/rails/generators/active_groonga/model/templates/module.rb +5 -0
- data/test-unit-notify/COPYING +502 -0
- data/test-unit-notify/Rakefile +47 -0
- data/test-unit-notify/lib/test/unit/notify.rb +127 -0
- data/test-unit/COPYING +56 -0
- data/test-unit/GPL +340 -0
- data/test-unit/PSFL +271 -0
- data/test-unit/Rakefile +18 -5
- data/test-unit/html/bar.svg +153 -0
- data/test-unit/html/developer.svg +469 -0
- data/test-unit/html/favicon.ico +0 -0
- data/test-unit/html/favicon.svg +82 -0
- data/test-unit/html/heading-mark.svg +393 -0
- data/test-unit/html/index.html +235 -13
- data/test-unit/html/index.html.ja +258 -15
- data/test-unit/html/install.svg +636 -0
- data/test-unit/html/logo.svg +483 -0
- data/test-unit/html/test-unit.css +339 -0
- data/test-unit/html/tutorial.svg +559 -0
- data/test-unit/lib/test/unit.rb +29 -43
- data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
- data/test-unit/lib/test/unit/assertions.rb +202 -20
- data/test-unit/lib/test/unit/autorunner.rb +51 -20
- data/test-unit/lib/test/unit/collector.rb +1 -8
- data/test-unit/lib/test/unit/collector/dir.rb +1 -1
- data/test-unit/lib/test/unit/collector/load.rb +16 -9
- data/test-unit/lib/test/unit/color-scheme.rb +19 -3
- data/test-unit/lib/test/unit/diff.rb +240 -38
- data/test-unit/lib/test/unit/error.rb +4 -0
- data/test-unit/lib/test/unit/failure.rb +31 -5
- data/test-unit/lib/test/unit/notification.rb +8 -4
- data/test-unit/lib/test/unit/omission.rb +51 -3
- data/test-unit/lib/test/unit/pending.rb +4 -0
- data/test-unit/lib/test/unit/priority.rb +2 -3
- data/test-unit/lib/test/unit/testcase.rb +65 -7
- data/test-unit/lib/test/unit/testresult.rb +34 -2
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +197 -45
- data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
- data/test-unit/lib/test/unit/ui/tap/testrunner.rb +2 -12
- data/test-unit/lib/test/unit/ui/testrunner.rb +33 -0
- data/test-unit/lib/test/unit/util/backtracefilter.rb +1 -0
- data/test-unit/lib/test/unit/util/output.rb +31 -0
- data/test-unit/lib/test/unit/version.rb +1 -1
- data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
- data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
- data/test-unit/sample/test_user.rb +1 -0
- data/test-unit/test/collector/test-descendant.rb +2 -4
- data/test-unit/test/collector/test-load.rb +121 -8
- data/test-unit/test/collector/test_objectspace.rb +7 -5
- data/test-unit/test/run-test.rb +2 -0
- data/test-unit/test/test-color-scheme.rb +11 -2
- data/test-unit/test/test-diff.rb +48 -7
- data/test-unit/test/test-omission.rb +1 -1
- data/test-unit/test/test-testcase.rb +57 -20
- data/test-unit/test/test_assertions.rb +128 -13
- data/test-unit/test/ui/test_tap.rb +33 -0
- data/test-unit/test/util/test-output.rb +11 -0
- data/test/active-groonga-test-utils.rb +50 -36
- data/test/fixtures/site.rb +2 -0
- data/test/run-test.rb +36 -9
- data/test/test-associations.rb +5 -2
- data/test/test-base.rb +39 -31
- data/test/test-callbacks.rb +13 -3
- data/test/test-persistence.rb +53 -0
- data/{lib/active_groonga/observer.rb → test/test-result-set.rb} +14 -12
- data/test/test-schema.rb +85 -22
- data/{lib/active_groonga/rails_support.rb → test/test-validations.rb} +15 -13
- metadata +85 -52
- data/lib/active_groonga/associations.rb +0 -93
- data/lib/active_groonga/associations/belongs_to_association.rb +0 -25
- data/lib/active_groonga/attribute_methods.rb +0 -36
- data/lib/active_groonga/column.rb +0 -137
- data/lib/active_groonga/dynamic_record_expression_builder.rb +0 -40
- data/lib/active_groonga/reflection.rb +0 -30
- data/lib/active_groonga/schema_dumper.rb +0 -163
- data/lib/active_groonga/tasks.rb +0 -16
- data/lib/active_groonga/tasks/groonga.rake +0 -164
- data/lib/active_groonga/timestamp.rb +0 -30
- data/rails/README +0 -28
- data/rails/init.rb +0 -70
- data/rails_generators/index_table_groonga/USAGE +0 -23
- data/rails_generators/index_table_groonga/index_table_groonga_generator.rb +0 -44
- data/rails_generators/index_table_groonga/templates/migration.rb +0 -12
- data/rails_generators/migration_groonga/USAGE +0 -29
- data/rails_generators/migration_groonga/migration_groonga_generator.rb +0 -19
- data/rails_generators/migration_groonga/templates/migration.rb +0 -11
- data/rails_generators/model_groonga/USAGE +0 -28
- data/rails_generators/model_groonga/model_groonga_generator.rb +0 -45
- data/rails_generators/model_groonga/templates/fixtures.yml +0 -17
- data/rails_generators/model_groonga/templates/migration.rb +0 -16
- data/rails_generators/model_groonga/templates/model.rb +0 -2
- data/rails_generators/model_groonga/templates/unit_test.rb +0 -8
- data/test-unit/html/classic.html +0 -15
- data/test-unit/sample/ts_examples.rb +0 -7
- data/test/test-schema-dumper.rb +0 -48
|
@@ -11,16 +11,23 @@ module Test
|
|
|
11
11
|
# when an assertion fails.
|
|
12
12
|
class Failure
|
|
13
13
|
attr_reader :test_name, :location, :message
|
|
14
|
-
|
|
14
|
+
attr_reader :expected, :actual, :user_message
|
|
15
|
+
attr_reader :inspected_expected, :inspected_actual
|
|
16
|
+
|
|
15
17
|
SINGLE_CHARACTER = 'F'
|
|
16
18
|
LABEL = "Failure"
|
|
17
19
|
|
|
18
20
|
# Creates a new Failure with the given location and
|
|
19
21
|
# message.
|
|
20
|
-
def initialize(test_name, location, message)
|
|
22
|
+
def initialize(test_name, location, message, options={})
|
|
21
23
|
@test_name = test_name
|
|
22
24
|
@location = location
|
|
23
25
|
@message = message
|
|
26
|
+
@expected = options[:expected]
|
|
27
|
+
@actual = options[:actual]
|
|
28
|
+
@inspected_expected = options[:inspected_expected]
|
|
29
|
+
@inspected_actual = options[:inspected_actual]
|
|
30
|
+
@user_message = options[:user_message]
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
# Returns a single character representation of a failure.
|
|
@@ -51,6 +58,19 @@ module Test
|
|
|
51
58
|
def to_s
|
|
52
59
|
long_display
|
|
53
60
|
end
|
|
61
|
+
|
|
62
|
+
def critical?
|
|
63
|
+
true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def diff
|
|
67
|
+
@diff ||= compute_diff
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
def compute_diff
|
|
72
|
+
Assertions::AssertionMessage.delayed_diff(@expected, @actual).inspect
|
|
73
|
+
end
|
|
54
74
|
end
|
|
55
75
|
|
|
56
76
|
module FailureHandler
|
|
@@ -64,12 +84,18 @@ module Test
|
|
|
64
84
|
def handle_assertion_failed_error(exception)
|
|
65
85
|
return false unless exception.is_a?(AssertionFailedError)
|
|
66
86
|
problem_occurred
|
|
67
|
-
add_failure(exception.message, exception.backtrace
|
|
87
|
+
add_failure(exception.message, exception.backtrace,
|
|
88
|
+
:expected => exception.expected,
|
|
89
|
+
:actual => exception.actual,
|
|
90
|
+
:inspected_expected => exception.inspected_expected,
|
|
91
|
+
:inspected_actual => exception.inspected_actual,
|
|
92
|
+
:user_message => exception.user_message)
|
|
68
93
|
true
|
|
69
94
|
end
|
|
70
95
|
|
|
71
|
-
def add_failure(message, backtrace)
|
|
72
|
-
failure = Failure.new(name, filter_backtrace(backtrace), message
|
|
96
|
+
def add_failure(message, backtrace, options={})
|
|
97
|
+
failure = Failure.new(name, filter_backtrace(backtrace), message,
|
|
98
|
+
options)
|
|
73
99
|
current_result.add_failure(failure)
|
|
74
100
|
end
|
|
75
101
|
end
|
|
@@ -41,6 +41,10 @@ module Test
|
|
|
41
41
|
def to_s
|
|
42
42
|
long_display
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
def critical?
|
|
46
|
+
false
|
|
47
|
+
end
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
class NotifiedError < StandardError
|
|
@@ -79,16 +83,16 @@ module Test
|
|
|
79
83
|
module NotificationHandler
|
|
80
84
|
class << self
|
|
81
85
|
def included(base)
|
|
82
|
-
base.exception_handler(:
|
|
86
|
+
base.exception_handler(:handle_notified_error)
|
|
83
87
|
end
|
|
84
88
|
end
|
|
85
89
|
|
|
86
90
|
private
|
|
87
|
-
def
|
|
91
|
+
def handle_notified_error(exception)
|
|
88
92
|
return false unless exception.is_a?(NotifiedError)
|
|
89
93
|
notification = Notification.new(name,
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
filter_backtrace(exception.backtrace),
|
|
95
|
+
exception.message)
|
|
92
96
|
add_notification(notification)
|
|
93
97
|
true
|
|
94
98
|
end
|
|
@@ -41,6 +41,10 @@ module Test
|
|
|
41
41
|
def to_s
|
|
42
42
|
long_display
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
def critical?
|
|
46
|
+
true
|
|
47
|
+
end
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
class OmittedError < StandardError
|
|
@@ -56,7 +60,7 @@ module Test
|
|
|
56
60
|
end
|
|
57
61
|
end
|
|
58
62
|
|
|
59
|
-
# Omit the test
|
|
63
|
+
# Omit the test or part of the test.
|
|
60
64
|
#
|
|
61
65
|
# Example:
|
|
62
66
|
# def test_omission
|
|
@@ -80,12 +84,56 @@ module Test
|
|
|
80
84
|
end
|
|
81
85
|
end
|
|
82
86
|
|
|
87
|
+
# Omit the test or part of the test if _condition_ is
|
|
88
|
+
# true.
|
|
89
|
+
#
|
|
90
|
+
# Example:
|
|
91
|
+
# def test_omission
|
|
92
|
+
# omit_if("".empty?)
|
|
93
|
+
# # Not reached here
|
|
94
|
+
# end
|
|
95
|
+
#
|
|
96
|
+
# def test_omission_with_here
|
|
97
|
+
# omit_if(true) do
|
|
98
|
+
# # Not ran here
|
|
99
|
+
# end
|
|
100
|
+
# omit_if(false) do
|
|
101
|
+
# # Reached here
|
|
102
|
+
# end
|
|
103
|
+
# # Reached here too
|
|
104
|
+
# end
|
|
83
105
|
def omit_if(condition, *args, &block)
|
|
84
|
-
|
|
106
|
+
if condition
|
|
107
|
+
omit(*args, &block)
|
|
108
|
+
else
|
|
109
|
+
block.call if block
|
|
110
|
+
end
|
|
85
111
|
end
|
|
86
112
|
|
|
113
|
+
# Omit the test or part of the test if _condition_ is
|
|
114
|
+
# not true.
|
|
115
|
+
#
|
|
116
|
+
# Example:
|
|
117
|
+
# def test_omission
|
|
118
|
+
# omit_unless("string".empty?)
|
|
119
|
+
# # Not reached here
|
|
120
|
+
# end
|
|
121
|
+
#
|
|
122
|
+
# def test_omission_with_here
|
|
123
|
+
# omit_unless(true) do
|
|
124
|
+
# # Reached here
|
|
125
|
+
# end
|
|
126
|
+
# omit_unless(false) do
|
|
127
|
+
# # Not ran here
|
|
128
|
+
# end
|
|
129
|
+
# # Reached here too
|
|
130
|
+
# end
|
|
87
131
|
def omit_unless(condition, *args, &block)
|
|
88
|
-
|
|
132
|
+
if condition
|
|
133
|
+
block.call if block
|
|
134
|
+
else
|
|
135
|
+
omit(*args, &block)
|
|
136
|
+
end
|
|
89
137
|
end
|
|
90
138
|
|
|
91
139
|
private
|
|
@@ -19,6 +19,7 @@ require 'test/unit/priority'
|
|
|
19
19
|
require 'test/unit/testsuite'
|
|
20
20
|
require 'test/unit/assertionfailederror'
|
|
21
21
|
require 'test/unit/util/backtracefilter'
|
|
22
|
+
require 'test/unit/util/output'
|
|
22
23
|
require 'test/unit/util/method-owner-finder'
|
|
23
24
|
|
|
24
25
|
module Test
|
|
@@ -82,6 +83,7 @@ module Test
|
|
|
82
83
|
include Priority
|
|
83
84
|
include Assertions
|
|
84
85
|
include Util::BacktraceFilter
|
|
86
|
+
include Util::Output
|
|
85
87
|
|
|
86
88
|
STARTED = name + "::STARTED" # :nodoc:
|
|
87
89
|
FINISHED = name + "::FINISHED" # :nodoc:
|
|
@@ -94,10 +96,15 @@ module Test
|
|
|
94
96
|
DESCENDANTS << sub_class
|
|
95
97
|
end
|
|
96
98
|
|
|
97
|
-
@@added_methods =
|
|
99
|
+
@@added_methods = {}
|
|
98
100
|
def method_added(name) # :nodoc:
|
|
99
101
|
super
|
|
100
|
-
@@added_methods
|
|
102
|
+
added_methods = (@@added_methods[self] ||= [])
|
|
103
|
+
stringified_name = name.to_s
|
|
104
|
+
if added_methods.include?(stringified_name)
|
|
105
|
+
attribute(:redefined, true, {}, stringified_name)
|
|
106
|
+
end
|
|
107
|
+
added_methods << stringified_name
|
|
101
108
|
end
|
|
102
109
|
|
|
103
110
|
# Rolls up all of the test* methods in the fixture into
|
|
@@ -191,12 +198,12 @@ module Test
|
|
|
191
198
|
def shutdown
|
|
192
199
|
end
|
|
193
200
|
|
|
194
|
-
@@
|
|
201
|
+
@@test_orders = {}
|
|
195
202
|
|
|
196
203
|
# Returns the current test order. This returns
|
|
197
204
|
# +:alphabetic+ by default.
|
|
198
205
|
def test_order
|
|
199
|
-
@@
|
|
206
|
+
@@test_orders[self] || AVAILABLE_ORDERS.first
|
|
200
207
|
end
|
|
201
208
|
|
|
202
209
|
# Sets the current test order.
|
|
@@ -209,7 +216,40 @@ module Test
|
|
|
209
216
|
# [:defined]
|
|
210
217
|
# Tests are sorted in defined order.
|
|
211
218
|
def test_order=(order)
|
|
212
|
-
@@
|
|
219
|
+
@@test_orders[self] = order
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Defines a test in declarative syntax.
|
|
223
|
+
#
|
|
224
|
+
# The following two test definitions are the same:
|
|
225
|
+
#
|
|
226
|
+
# description "register user"
|
|
227
|
+
# def test_register_user
|
|
228
|
+
# ...
|
|
229
|
+
# end
|
|
230
|
+
#
|
|
231
|
+
# test "register user" do
|
|
232
|
+
# ...
|
|
233
|
+
# end
|
|
234
|
+
def test(test_description, &block)
|
|
235
|
+
normalized_description = test_description.gsub(/[^a-zA-Z\d_]+/, '_')
|
|
236
|
+
method_name = "test_#{normalized_description}".to_sym
|
|
237
|
+
define_method(method_name, &block)
|
|
238
|
+
description(test_description, method_name)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Describes a test.
|
|
242
|
+
#
|
|
243
|
+
# The following example associates "register a
|
|
244
|
+
# normal user" description with "test_register"
|
|
245
|
+
# test.
|
|
246
|
+
#
|
|
247
|
+
# description "register a normal user"
|
|
248
|
+
# def test_register
|
|
249
|
+
# ...
|
|
250
|
+
# end
|
|
251
|
+
def description(value, target=nil)
|
|
252
|
+
attribute(:description, value, {}, target || [])
|
|
213
253
|
end
|
|
214
254
|
|
|
215
255
|
# :stopdoc:
|
|
@@ -233,9 +273,10 @@ module Test
|
|
|
233
273
|
end
|
|
234
274
|
|
|
235
275
|
def sort_test_names_in_defined_order(test_names)
|
|
276
|
+
added_methods = @@added_methods[self]
|
|
236
277
|
test_names.sort do |test1, test2|
|
|
237
|
-
test1_defined_order =
|
|
238
|
-
test2_defined_order =
|
|
278
|
+
test1_defined_order = added_methods.index(test1)
|
|
279
|
+
test2_defined_order = added_methods.index(test2)
|
|
239
280
|
if test1_defined_order and test2_defined_order
|
|
240
281
|
test1_defined_order <=> test2_defined_order
|
|
241
282
|
elsif test1_defined_order
|
|
@@ -374,6 +415,15 @@ module Test
|
|
|
374
415
|
"#{@method_name}(#{self.class.name})"
|
|
375
416
|
end
|
|
376
417
|
|
|
418
|
+
# Returns a description for the test. A description
|
|
419
|
+
# will be associated by Test::Unit::TestCase.test or
|
|
420
|
+
# Test::Unit::TestCase.description.
|
|
421
|
+
#
|
|
422
|
+
# Returns a name for the test for no description test.
|
|
423
|
+
def description
|
|
424
|
+
self[:description] || name
|
|
425
|
+
end
|
|
426
|
+
|
|
377
427
|
# Overridden to return #name.
|
|
378
428
|
def to_s
|
|
379
429
|
name
|
|
@@ -396,7 +446,11 @@ module Test
|
|
|
396
446
|
end
|
|
397
447
|
|
|
398
448
|
def run_test
|
|
449
|
+
if self.class.get_attribute(@method_name, :redefined)
|
|
450
|
+
notify("#{self.class}\##{@method_name} was redefined")
|
|
451
|
+
end
|
|
399
452
|
__send__(@method_name)
|
|
453
|
+
add_pass
|
|
400
454
|
end
|
|
401
455
|
|
|
402
456
|
def handle_exception(exception)
|
|
@@ -420,6 +474,10 @@ module Test
|
|
|
420
474
|
def add_assertion
|
|
421
475
|
current_result.add_assertion
|
|
422
476
|
end
|
|
477
|
+
|
|
478
|
+
def add_pass
|
|
479
|
+
current_result.add_pass
|
|
480
|
+
end
|
|
423
481
|
end
|
|
424
482
|
end
|
|
425
483
|
end
|
|
@@ -34,11 +34,11 @@ module Test
|
|
|
34
34
|
CHANGED = "CHANGED"
|
|
35
35
|
FAULT = "FAULT"
|
|
36
36
|
|
|
37
|
-
attr_reader :run_count, :assertion_count, :faults
|
|
37
|
+
attr_reader :run_count, :pass_count, :assertion_count, :faults
|
|
38
38
|
|
|
39
39
|
# Constructs a new, empty TestResult.
|
|
40
40
|
def initialize
|
|
41
|
-
@run_count, @assertion_count = 0, 0
|
|
41
|
+
@run_count, @pass_count, @assertion_count = 0, 0, 0
|
|
42
42
|
@summary_generators = []
|
|
43
43
|
@problem_checkers = []
|
|
44
44
|
@faults = []
|
|
@@ -51,6 +51,10 @@ module Test
|
|
|
51
51
|
notify_changed
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
def add_pass
|
|
55
|
+
@pass_count += 1
|
|
56
|
+
end
|
|
57
|
+
|
|
54
58
|
# Records an individual assertion.
|
|
55
59
|
def add_assertion
|
|
56
60
|
@assertion_count += 1
|
|
@@ -65,6 +69,25 @@ module Test
|
|
|
65
69
|
*@summary_generators.collect {|generator| send(generator)}].join(", ")
|
|
66
70
|
end
|
|
67
71
|
|
|
72
|
+
# Returnes a string that shows result status.
|
|
73
|
+
def status
|
|
74
|
+
if passed?
|
|
75
|
+
if pending_count > 0
|
|
76
|
+
"pending"
|
|
77
|
+
elsif omission_count > 0
|
|
78
|
+
"omission"
|
|
79
|
+
elsif notification_count > 0
|
|
80
|
+
"notification"
|
|
81
|
+
else
|
|
82
|
+
"pass"
|
|
83
|
+
end
|
|
84
|
+
elsif error_count > 0
|
|
85
|
+
"error"
|
|
86
|
+
elsif failure_count > 0
|
|
87
|
+
"failure"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
68
91
|
def to_s
|
|
69
92
|
summary
|
|
70
93
|
end
|
|
@@ -75,6 +98,15 @@ module Test
|
|
|
75
98
|
@problem_checkers.all? {|checker| not send(checker)}
|
|
76
99
|
end
|
|
77
100
|
|
|
101
|
+
def pass_percentage
|
|
102
|
+
n_tests = @run_count - omission_count
|
|
103
|
+
if n_tests.zero?
|
|
104
|
+
0
|
|
105
|
+
else
|
|
106
|
+
100.0 * (@pass_count / n_tests.to_f)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
78
110
|
private
|
|
79
111
|
def notify_changed
|
|
80
112
|
notify_listeners(CHANGED, self)
|
|
@@ -38,22 +38,14 @@ module Test
|
|
|
38
38
|
@progress_row_max = @options[:progress_row_max]
|
|
39
39
|
@progress_row_max ||= guess_progress_row_max
|
|
40
40
|
@already_outputted = false
|
|
41
|
-
@n_successes = 0
|
|
42
41
|
@indent = 0
|
|
43
42
|
@top_level = true
|
|
44
43
|
@faults = []
|
|
45
44
|
end
|
|
46
45
|
|
|
47
|
-
# Begins the test run.
|
|
48
|
-
def start
|
|
49
|
-
setup_mediator
|
|
50
|
-
attach_to_mediator
|
|
51
|
-
return start_mediator
|
|
52
|
-
end
|
|
53
|
-
|
|
54
46
|
private
|
|
55
47
|
def setup_mediator
|
|
56
|
-
|
|
48
|
+
super
|
|
57
49
|
output_setup_end
|
|
58
50
|
end
|
|
59
51
|
|
|
@@ -63,10 +55,6 @@ module Test
|
|
|
63
55
|
output("Loaded suite #{suite_name}")
|
|
64
56
|
end
|
|
65
57
|
|
|
66
|
-
def create_mediator(suite)
|
|
67
|
-
return TestRunnerMediator.new(suite)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
58
|
def attach_to_mediator
|
|
71
59
|
@mediator.add_listener(TestResult::FAULT, &method(:add_fault))
|
|
72
60
|
@mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
|
|
@@ -77,14 +65,10 @@ module Test
|
|
|
77
65
|
@mediator.add_listener(TestSuite::FINISHED, &method(:test_suite_finished))
|
|
78
66
|
end
|
|
79
67
|
|
|
80
|
-
def start_mediator
|
|
81
|
-
return @mediator.run_suite
|
|
82
|
-
end
|
|
83
|
-
|
|
84
68
|
def add_fault(fault)
|
|
85
69
|
@faults << fault
|
|
86
70
|
output_progress(fault.single_character_display, fault_color(fault))
|
|
87
|
-
@already_outputted = true
|
|
71
|
+
@already_outputted = true if fault.critical?
|
|
88
72
|
end
|
|
89
73
|
|
|
90
74
|
def started(result)
|
|
@@ -101,21 +85,72 @@ module Test
|
|
|
101
85
|
@faults.each_with_index do |fault, index|
|
|
102
86
|
nl
|
|
103
87
|
output_single("%3d) " % (index + 1))
|
|
104
|
-
|
|
105
|
-
output(label, fault_color(fault))
|
|
106
|
-
output(detail)
|
|
88
|
+
output_fault(fault)
|
|
107
89
|
end
|
|
108
90
|
nl
|
|
109
91
|
output("Finished in #{elapsed_time} seconds.")
|
|
110
92
|
nl
|
|
111
93
|
output(@result, result_color)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
94
|
+
output("%g%% passed" % @result.pass_percentage, result_color)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def output_fault(fault)
|
|
98
|
+
if @use_color and fault.is_a?(Failure) and
|
|
99
|
+
fault.inspected_expected and fault.inspected_actual
|
|
100
|
+
output_single(fault.label, fault_color(fault))
|
|
101
|
+
output(":")
|
|
102
|
+
output_fault_backtrace(fault)
|
|
103
|
+
output_fault_message(fault)
|
|
115
104
|
else
|
|
116
|
-
|
|
105
|
+
label, detail = format_fault(fault).split(/\r?\n/, 2)
|
|
106
|
+
output(label, fault_color(fault))
|
|
107
|
+
output(detail)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def output_fault_backtrace(fault)
|
|
112
|
+
backtrace = fault.location
|
|
113
|
+
if backtrace.size == 1
|
|
114
|
+
output(fault.test_name +
|
|
115
|
+
backtrace[0].sub(/\A(.+:\d+).*/, ' [\\1]') +
|
|
116
|
+
":")
|
|
117
|
+
else
|
|
118
|
+
output(fault.test_name)
|
|
119
|
+
backtrace.each_with_index do |entry, i|
|
|
120
|
+
if i.zero?
|
|
121
|
+
prefix = "["
|
|
122
|
+
postfix = ""
|
|
123
|
+
elsif i == backtrace.size - 1
|
|
124
|
+
prefix = " "
|
|
125
|
+
postfix = "]:"
|
|
126
|
+
else
|
|
127
|
+
prefix = " "
|
|
128
|
+
postfix = ""
|
|
129
|
+
end
|
|
130
|
+
output(" #{prefix}#{entry}#{postfix}")
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def output_fault_message(fault)
|
|
136
|
+
output(fault.user_message) if fault.user_message
|
|
137
|
+
output_single("<")
|
|
138
|
+
output_single(fault.inspected_expected, color("pass"))
|
|
139
|
+
output("> expected but was")
|
|
140
|
+
output_single("<")
|
|
141
|
+
output_single(fault.inspected_actual, color("failure"))
|
|
142
|
+
output(">")
|
|
143
|
+
from, to = prepare_for_diff(fault.expected, fault.actual)
|
|
144
|
+
if from and to
|
|
145
|
+
differ = ColorizedReadableDiffer.new(from.split(/\r?\n/),
|
|
146
|
+
to.split(/\r?\n/),
|
|
147
|
+
self)
|
|
148
|
+
if differ.need_diff?
|
|
149
|
+
output("")
|
|
150
|
+
output("diff:")
|
|
151
|
+
differ.diff
|
|
152
|
+
end
|
|
117
153
|
end
|
|
118
|
-
output("%g%% passed" % pass_percentage, result_color)
|
|
119
154
|
end
|
|
120
155
|
|
|
121
156
|
def format_fault(fault)
|
|
@@ -129,15 +164,14 @@ module Test
|
|
|
129
164
|
right_space = 8 * 2
|
|
130
165
|
left_space = @progress_row_max - right_space
|
|
131
166
|
left_space = left_space - indent.size - name.size
|
|
132
|
-
tab_stop = "\t" * (
|
|
167
|
+
tab_stop = "\t" * ([left_space - 1, 0].max / 8)
|
|
133
168
|
output_single("#{indent}#{name}:#{tab_stop}", nil, VERBOSE)
|
|
134
169
|
@test_start = Time.now
|
|
135
170
|
end
|
|
136
171
|
|
|
137
172
|
def test_finished(name)
|
|
138
173
|
unless @already_outputted
|
|
139
|
-
|
|
140
|
-
output_progress(".", color("success"))
|
|
174
|
+
output_progress(".", color("pass"))
|
|
141
175
|
end
|
|
142
176
|
@already_outputted = false
|
|
143
177
|
|
|
@@ -213,7 +247,10 @@ module Test
|
|
|
213
247
|
end
|
|
214
248
|
|
|
215
249
|
def color(name)
|
|
216
|
-
@color_scheme[name]
|
|
250
|
+
_color = @color_scheme[name]
|
|
251
|
+
_color ||= @color_scheme["success"] if name == "pass"
|
|
252
|
+
_color ||= ColorScheme.default[name]
|
|
253
|
+
_color
|
|
217
254
|
end
|
|
218
255
|
|
|
219
256
|
def fault_color(fault)
|
|
@@ -221,21 +258,7 @@ module Test
|
|
|
221
258
|
end
|
|
222
259
|
|
|
223
260
|
def result_color
|
|
224
|
-
|
|
225
|
-
if @result.pending_count > 0
|
|
226
|
-
color("pending")
|
|
227
|
-
elsif @result.omission_count > 0
|
|
228
|
-
color("omission")
|
|
229
|
-
elsif @result.notification_count > 0
|
|
230
|
-
color("notification")
|
|
231
|
-
else
|
|
232
|
-
color("success")
|
|
233
|
-
end
|
|
234
|
-
elsif @result.error_count > 0
|
|
235
|
-
color("error")
|
|
236
|
-
elsif @result.failure_count > 0
|
|
237
|
-
color("failure")
|
|
238
|
-
end
|
|
261
|
+
color(@result.status)
|
|
239
262
|
end
|
|
240
263
|
|
|
241
264
|
def guess_color_availability
|
|
@@ -268,6 +291,135 @@ module Test
|
|
|
268
291
|
0
|
|
269
292
|
end
|
|
270
293
|
end
|
|
294
|
+
|
|
295
|
+
class ColorizedReadableDiffer < Diff::ReadableDiffer
|
|
296
|
+
def initialize(from, to, runner)
|
|
297
|
+
@runner = runner
|
|
298
|
+
super(from, to)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def need_diff?(options={})
|
|
302
|
+
operations.each do |tag,|
|
|
303
|
+
return true if [:replace, :equal].include?(tag)
|
|
304
|
+
end
|
|
305
|
+
false
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
private
|
|
309
|
+
def output_single(something, color=nil)
|
|
310
|
+
@runner.send(:output_single, something, color)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def output(something, color=nil)
|
|
314
|
+
@runner.send(:output, something, color)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def color(name)
|
|
318
|
+
@runner.send(:color, name)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def cut_off_ratio
|
|
322
|
+
0
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def default_ratio
|
|
326
|
+
0
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def tag(mark, color_name, contents)
|
|
330
|
+
_color = color(color_name)
|
|
331
|
+
contents.each do |content|
|
|
332
|
+
output_single(mark, _color)
|
|
333
|
+
output_single(" ")
|
|
334
|
+
output(content)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def tag_deleted(contents)
|
|
339
|
+
tag("-", "diff-deleted-tag", contents)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def tag_inserted(contents)
|
|
343
|
+
tag("+", "diff-inserted-tag", contents)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def tag_equal(contents)
|
|
347
|
+
tag(" ", "normal", contents)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def tag_difference(contents)
|
|
351
|
+
tag("?", "diff-difference-tag", contents)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def diff_line(from_line, to_line)
|
|
355
|
+
to_operations = []
|
|
356
|
+
from_line, to_line, _operations = line_operations(from_line, to_line)
|
|
357
|
+
|
|
358
|
+
no_replace = true
|
|
359
|
+
_operations.each do |tag,|
|
|
360
|
+
if tag == :replace
|
|
361
|
+
no_replace = false
|
|
362
|
+
break
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
output_single("?", color("diff-difference-tag"))
|
|
367
|
+
output_single(" ")
|
|
368
|
+
_operations.each do |tag, from_start, from_end, to_start, to_end|
|
|
369
|
+
from_width = compute_width(from_line, from_start, from_end)
|
|
370
|
+
to_width = compute_width(to_line, to_start, to_end)
|
|
371
|
+
case tag
|
|
372
|
+
when :replace
|
|
373
|
+
output_single(from_line[from_start...from_end],
|
|
374
|
+
color("diff-deleted"))
|
|
375
|
+
if (from_width < to_width)
|
|
376
|
+
output_single(" " * (to_width - from_width))
|
|
377
|
+
end
|
|
378
|
+
to_operations << Proc.new do
|
|
379
|
+
output_single(to_line[to_start...to_end],
|
|
380
|
+
color("diff-inserted"))
|
|
381
|
+
if (to_width < from_width)
|
|
382
|
+
output_single(" " * (from_width - to_width))
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
when :delete
|
|
386
|
+
output_single(from_line[from_start...from_end],
|
|
387
|
+
color("diff-deleted"))
|
|
388
|
+
unless no_replace
|
|
389
|
+
to_operations << Proc.new {output_single(" " * from_width)}
|
|
390
|
+
end
|
|
391
|
+
when :insert
|
|
392
|
+
if no_replace
|
|
393
|
+
output_single(to_line[to_start...to_end],
|
|
394
|
+
color("diff-inserted"))
|
|
395
|
+
else
|
|
396
|
+
output_single(" " * to_width)
|
|
397
|
+
to_operations << Proc.new do
|
|
398
|
+
output_single(to_line[to_start...to_end],
|
|
399
|
+
color("diff-inserted"))
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
when :equal
|
|
403
|
+
output_single(from_line[from_start...from_end])
|
|
404
|
+
unless no_replace
|
|
405
|
+
to_operations << Proc.new {output_single(" " * to_width)}
|
|
406
|
+
end
|
|
407
|
+
else
|
|
408
|
+
raise "unknown tag: #{tag}"
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
output("")
|
|
412
|
+
|
|
413
|
+
unless to_operations.empty?
|
|
414
|
+
output_single("?", color("diff-difference-tag"))
|
|
415
|
+
output_single(" ")
|
|
416
|
+
to_operations.each do |operation|
|
|
417
|
+
operation.call
|
|
418
|
+
end
|
|
419
|
+
output("")
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
271
423
|
end
|
|
272
424
|
end
|
|
273
425
|
end
|