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.
Files changed (122) hide show
  1. data/README.ja.rdoc +4 -1
  2. data/README.rdoc +4 -1
  3. data/Rakefile +18 -4
  4. data/lib/active_groonga.rb +25 -52
  5. data/lib/active_groonga/base.rb +164 -1480
  6. data/lib/active_groonga/callbacks.rb +26 -7
  7. data/lib/active_groonga/database.rb +55 -0
  8. data/lib/active_groonga/{dirty.rb → error.rb} +20 -10
  9. data/lib/active_groonga/locale/en.yml +5 -0
  10. data/lib/active_groonga/migration.rb +44 -113
  11. data/lib/active_groonga/migrator.rb +172 -0
  12. data/lib/active_groonga/persistence.rb +172 -0
  13. data/lib/active_groonga/railtie.rb +66 -0
  14. data/lib/active_groonga/railties/configurable.rb +47 -0
  15. data/lib/active_groonga/railties/groonga.rake +167 -0
  16. data/lib/active_groonga/result_set.rb +89 -0
  17. data/lib/active_groonga/schema.rb +54 -188
  18. data/lib/active_groonga/validations.rb +54 -5
  19. data/lib/active_groonga/vector.rb +64 -0
  20. data/lib/active_groonga/version.rb +3 -3
  21. data/lib/{active_groonga/aggregations.rb → rails/generators/active_groonga.rb} +17 -10
  22. data/lib/rails/generators/active_groonga/migration/column.rb +101 -0
  23. data/lib/rails/generators/active_groonga/migration/migration_generator.rb +53 -0
  24. data/lib/rails/generators/active_groonga/migration/templates/migration.rb +29 -0
  25. data/lib/rails/generators/active_groonga/model/model_generator.rb +60 -0
  26. data/lib/rails/generators/active_groonga/model/templates/migration.rb +16 -0
  27. data/lib/rails/generators/active_groonga/model/templates/model.rb +2 -0
  28. data/lib/rails/generators/active_groonga/model/templates/module.rb +5 -0
  29. data/test-unit-notify/COPYING +502 -0
  30. data/test-unit-notify/Rakefile +47 -0
  31. data/test-unit-notify/lib/test/unit/notify.rb +127 -0
  32. data/test-unit/COPYING +56 -0
  33. data/test-unit/GPL +340 -0
  34. data/test-unit/PSFL +271 -0
  35. data/test-unit/Rakefile +18 -5
  36. data/test-unit/html/bar.svg +153 -0
  37. data/test-unit/html/developer.svg +469 -0
  38. data/test-unit/html/favicon.ico +0 -0
  39. data/test-unit/html/favicon.svg +82 -0
  40. data/test-unit/html/heading-mark.svg +393 -0
  41. data/test-unit/html/index.html +235 -13
  42. data/test-unit/html/index.html.ja +258 -15
  43. data/test-unit/html/install.svg +636 -0
  44. data/test-unit/html/logo.svg +483 -0
  45. data/test-unit/html/test-unit.css +339 -0
  46. data/test-unit/html/tutorial.svg +559 -0
  47. data/test-unit/lib/test/unit.rb +29 -43
  48. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  49. data/test-unit/lib/test/unit/assertions.rb +202 -20
  50. data/test-unit/lib/test/unit/autorunner.rb +51 -20
  51. data/test-unit/lib/test/unit/collector.rb +1 -8
  52. data/test-unit/lib/test/unit/collector/dir.rb +1 -1
  53. data/test-unit/lib/test/unit/collector/load.rb +16 -9
  54. data/test-unit/lib/test/unit/color-scheme.rb +19 -3
  55. data/test-unit/lib/test/unit/diff.rb +240 -38
  56. data/test-unit/lib/test/unit/error.rb +4 -0
  57. data/test-unit/lib/test/unit/failure.rb +31 -5
  58. data/test-unit/lib/test/unit/notification.rb +8 -4
  59. data/test-unit/lib/test/unit/omission.rb +51 -3
  60. data/test-unit/lib/test/unit/pending.rb +4 -0
  61. data/test-unit/lib/test/unit/priority.rb +2 -3
  62. data/test-unit/lib/test/unit/testcase.rb +65 -7
  63. data/test-unit/lib/test/unit/testresult.rb +34 -2
  64. data/test-unit/lib/test/unit/ui/console/testrunner.rb +197 -45
  65. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  66. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +2 -12
  67. data/test-unit/lib/test/unit/ui/testrunner.rb +33 -0
  68. data/test-unit/lib/test/unit/util/backtracefilter.rb +1 -0
  69. data/test-unit/lib/test/unit/util/output.rb +31 -0
  70. data/test-unit/lib/test/unit/version.rb +1 -1
  71. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  72. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  73. data/test-unit/sample/test_user.rb +1 -0
  74. data/test-unit/test/collector/test-descendant.rb +2 -4
  75. data/test-unit/test/collector/test-load.rb +121 -8
  76. data/test-unit/test/collector/test_objectspace.rb +7 -5
  77. data/test-unit/test/run-test.rb +2 -0
  78. data/test-unit/test/test-color-scheme.rb +11 -2
  79. data/test-unit/test/test-diff.rb +48 -7
  80. data/test-unit/test/test-omission.rb +1 -1
  81. data/test-unit/test/test-testcase.rb +57 -20
  82. data/test-unit/test/test_assertions.rb +128 -13
  83. data/test-unit/test/ui/test_tap.rb +33 -0
  84. data/test-unit/test/util/test-output.rb +11 -0
  85. data/test/active-groonga-test-utils.rb +50 -36
  86. data/test/fixtures/site.rb +2 -0
  87. data/test/run-test.rb +36 -9
  88. data/test/test-associations.rb +5 -2
  89. data/test/test-base.rb +39 -31
  90. data/test/test-callbacks.rb +13 -3
  91. data/test/test-persistence.rb +53 -0
  92. data/{lib/active_groonga/observer.rb → test/test-result-set.rb} +14 -12
  93. data/test/test-schema.rb +85 -22
  94. data/{lib/active_groonga/rails_support.rb → test/test-validations.rb} +15 -13
  95. metadata +85 -52
  96. data/lib/active_groonga/associations.rb +0 -93
  97. data/lib/active_groonga/associations/belongs_to_association.rb +0 -25
  98. data/lib/active_groonga/attribute_methods.rb +0 -36
  99. data/lib/active_groonga/column.rb +0 -137
  100. data/lib/active_groonga/dynamic_record_expression_builder.rb +0 -40
  101. data/lib/active_groonga/reflection.rb +0 -30
  102. data/lib/active_groonga/schema_dumper.rb +0 -163
  103. data/lib/active_groonga/tasks.rb +0 -16
  104. data/lib/active_groonga/tasks/groonga.rake +0 -164
  105. data/lib/active_groonga/timestamp.rb +0 -30
  106. data/rails/README +0 -28
  107. data/rails/init.rb +0 -70
  108. data/rails_generators/index_table_groonga/USAGE +0 -23
  109. data/rails_generators/index_table_groonga/index_table_groonga_generator.rb +0 -44
  110. data/rails_generators/index_table_groonga/templates/migration.rb +0 -12
  111. data/rails_generators/migration_groonga/USAGE +0 -29
  112. data/rails_generators/migration_groonga/migration_groonga_generator.rb +0 -19
  113. data/rails_generators/migration_groonga/templates/migration.rb +0 -11
  114. data/rails_generators/model_groonga/USAGE +0 -28
  115. data/rails_generators/model_groonga/model_groonga_generator.rb +0 -45
  116. data/rails_generators/model_groonga/templates/fixtures.yml +0 -17
  117. data/rails_generators/model_groonga/templates/migration.rb +0 -16
  118. data/rails_generators/model_groonga/templates/model.rb +0 -2
  119. data/rails_generators/model_groonga/templates/unit_test.rb +0 -8
  120. data/test-unit/html/classic.html +0 -15
  121. data/test-unit/sample/ts_examples.rb +0 -7
  122. data/test/test-schema-dumper.rb +0 -48
@@ -90,8 +90,13 @@ module Test # :nodoc:
90
90
  #
91
91
  # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free
92
92
  # software, and is distributed under the Ruby license. See the COPYING
93
- # file in the standard Ruby distribution for details.
93
+ # file.
94
94
  #
95
+ # Exception: lib/test/unit/diff.rb is copyright (c)
96
+ # 2008-2010 Kouhei Sutou and 2001-2008 Python Software
97
+ # Foundation. It is free software, and is distributed
98
+ # under the Ruby license and/or the PSF license. See the
99
+ # COPYING file and PSFL file.
95
100
  #
96
101
  # == Warranty
97
102
  #
@@ -179,7 +184,7 @@ module Test # :nodoc:
179
184
  #
180
185
  # require 'test/unit'
181
186
  #
182
- # class TC_MyTest < Test::Unit::TestCase
187
+ # class MyTest < Test::Unit::TestCase
183
188
  # # def setup
184
189
  # # end
185
190
  #
@@ -194,21 +199,17 @@ module Test # :nodoc:
194
199
  #
195
200
  # == Test Runners
196
201
  #
197
- # So, now you have this great test class, but you still need a way to
198
- # run it and view any failures that occur during the run. This is
199
- # where Test::Unit::UI::Console::TestRunner (and others, such as
200
- # Test::Unit::UI::GTK::TestRunner) comes into play. The console test
201
- # runner is automatically invoked for you if you require 'test/unit'
202
- # and simply run the file. To use another runner, or to manually
203
- # invoke a runner, simply call its run class method and pass in an
204
- # object that responds to the suite message with a
205
- # Test::Unit::TestSuite. This can be as simple as passing in your
206
- # TestCase class (which has a class suite method). It might look
207
- # something like this:
208
- #
209
- # require 'test/unit/ui/console/testrunner'
210
- # Test::Unit::UI::Console::TestRunner.run(TC_MyTest)
202
+ # So, now you have this great test class, but you still
203
+ # need a way to run it and view any failures that occur
204
+ # during the run. There are some test runner; console test
205
+ # runner, GTK+ test runner and so on. The console test
206
+ # runner is automatically invoked for you if you require
207
+ # 'test/unit' and simply run the file. To use another
208
+ # runner simply set default test runner ID to
209
+ # Test::Unit::AutoRunner:
211
210
  #
211
+ # require 'test/unit'
212
+ # Test::Unit::AutoRunner.default_runner = "gtk2"
212
213
  #
213
214
  # == Test Suite
214
215
  #
@@ -220,33 +221,17 @@ module Test # :nodoc:
220
221
  # in response to a suite method. The TestSuite can, in turn, contain
221
222
  # other TestSuites or individual tests (typically created by a
222
223
  # TestCase). In other words, you can easily wrap up a group of
223
- # TestCases and TestSuites like this:
224
- #
225
- # require 'test/unit/testsuite'
226
- # require 'tc_myfirsttests'
227
- # require 'tc_moretestsbyme'
228
- # require 'ts_anothersetoftests'
229
- #
230
- # class TS_MyTests
231
- # def self.suite
232
- # suite = Test::Unit::TestSuite.new
233
- # suite << TC_MyFirstTests.suite
234
- # suite << TC_MoreTestsByMe.suite
235
- # suite << TS_AnotherSetOfTests.suite
236
- # return suite
237
- # end
238
- # end
239
- # Test::Unit::UI::Console::TestRunner.run(TS_MyTests)
240
- #
241
- # Now, this is a bit cumbersome, so Test::Unit does a little bit more
242
- # for you, by wrapping these up automatically when you require
243
- # 'test/unit'. What does this mean? It means you could write the above
244
- # test case like this instead:
224
+ # TestCases and TestSuites.
225
+ #
226
+ # Test::Unit does a little bit more for you, by wrapping
227
+ # these up automatically when you require
228
+ # 'test/unit'. What does this mean? It means you could
229
+ # write the above test case like this instead:
245
230
  #
246
231
  # require 'test/unit'
247
- # require 'tc_myfirsttests'
248
- # require 'tc_moretestsbyme'
249
- # require 'ts_anothersetoftests'
232
+ # require 'test_myfirsttests'
233
+ # require 'test_moretestsbyme'
234
+ # require 'test_anothersetoftests'
250
235
  #
251
236
  # Test::Unit is smart enough to find all the test cases existing in
252
237
  # the ObjectSpace and wrap them up into a suite for you. It then runs
@@ -323,12 +308,13 @@ module Test # :nodoc:
323
308
  #
324
309
 
325
310
  module Unit
326
- # If set to false Test::Unit will not automatically run at exit.
311
+ # Set true when Test::Unit has run. If set to true Test::Unit
312
+ # will not automatically run at exit.
327
313
  def self.run=(flag)
328
314
  @run = flag
329
315
  end
330
316
 
331
- # Automatically run tests at exit?
317
+ # Already tests have run?
332
318
  def self.run?
333
319
  @run ||= false
334
320
  end
@@ -9,6 +9,17 @@ module Test
9
9
 
10
10
  # Thrown by Test::Unit::Assertions when an assertion fails.
11
11
  class AssertionFailedError < StandardError
12
+ attr_accessor :expected, :actual, :user_message
13
+ attr_accessor :inspected_expected, :inspected_actual
14
+ def initialize(message=nil, options=nil)
15
+ options ||= {}
16
+ @expected = options[:expected]
17
+ @actual = options[:actual]
18
+ @inspected_expected = options[:inspected_expected]
19
+ @inspected_actual = options[:inspected_actual]
20
+ @user_message = options[:user_message]
21
+ super(message)
22
+ end
12
23
  end
13
24
  end
14
25
  end
@@ -1,6 +1,6 @@
1
1
  # Author:: Nathaniel Talbott.
2
2
  # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
3
- # Copyright (c) 2009 Kouhei Sutou.
3
+ # Copyright (c) 2009-2010 Kouhei Sutou. All rights reserved.
4
4
  # License:: Ruby license.
5
5
 
6
6
  require 'test/unit/assertionfailederror'
@@ -80,11 +80,33 @@ module Test
80
80
  public
81
81
  def assert_equal(expected, actual, message=nil)
82
82
  diff = AssertionMessage.delayed_diff(expected, actual)
83
- full_message = build_message(message, <<EOT, expected, actual, diff)
83
+ if expected.respond_to?(:encoding) and
84
+ actual.respond_to?(:encoding) and
85
+ expected.encoding != actual.encoding
86
+ format = <<EOT
87
+ <?>(?) expected but was
88
+ <?>(?).?
89
+ EOT
90
+ full_message = build_message(message, format,
91
+ expected, expected.encoding.name,
92
+ actual, actual.encoding.name,
93
+ diff)
94
+ else
95
+ full_message = build_message(message, <<EOT, expected, actual, diff)
84
96
  <?> expected but was
85
97
  <?>.?
86
98
  EOT
87
- assert_block(full_message) { expected == actual }
99
+ end
100
+ begin
101
+ assert_block(full_message) { expected == actual }
102
+ rescue AssertionFailedError => failure
103
+ failure.expected = expected
104
+ failure.actual = actual
105
+ failure.inspected_expected = AssertionMessage.convert(expected)
106
+ failure.inspected_actual = AssertionMessage.convert(actual)
107
+ failure.user_message = message
108
+ raise
109
+ end
88
110
  end
89
111
 
90
112
  ##
@@ -530,18 +552,73 @@ EOT
530
552
  public
531
553
  def assert_in_delta(expected_float, actual_float, delta, message="")
532
554
  _wrap_assertion do
533
- {expected_float => "first float", actual_float => "second float", delta => "delta"}.each do |float, name|
534
- assert_respond_to(float, :to_f, "The arguments must respond to to_f; the #{name} did not")
535
- end
536
- assert_operator(delta, :>=, 0.0, "The delta should not be negative")
537
- full_message = build_message(message, <<EOT, expected_float, actual_float, delta)
538
- <?> and
539
- <?> expected to be within
540
- <?> of each other.
555
+ _assert_in_delta_validate_arguments(expected_float,
556
+ actual_float,
557
+ delta)
558
+ full_message = _assert_in_delta_message(expected_float,
559
+ actual_float,
560
+ delta,
561
+ message)
562
+ assert_block(full_message) do
563
+ (expected_float.to_f - actual_float.to_f).abs <= delta.to_f
564
+ end
565
+ end
566
+ end
567
+
568
+ # :stopdoc:
569
+ private
570
+ def _assert_in_delta_validate_arguments(expected_float,
571
+ actual_float,
572
+ delta)
573
+ {
574
+ expected_float => "first float",
575
+ actual_float => "second float",
576
+ delta => "delta"
577
+ }.each do |float, name|
578
+ assert_respond_to(float, :to_f,
579
+ "The arguments must respond to to_f; " +
580
+ "the #{name} did not")
581
+ end
582
+ assert_operator(delta, :>=, 0.0, "The delta should not be negative")
583
+ end
584
+
585
+ def _assert_in_delta_message(expected_float, actual_float, delta,
586
+ message)
587
+ format = <<-EOT
588
+ <?> expected but was
589
+ <?> (tolerance <?>).
590
+ EOT
591
+ arguments = [expected_float, actual_float, delta]
592
+ normalized_expected = expected_float.to_f
593
+ normalized_actual = actual_float.to_f
594
+ normalized_delta = delta.to_f
595
+ relation_format = nil
596
+ relation_arguments = nil
597
+ if normalized_actual < normalized_expected - normalized_delta
598
+ relation_format = "<<?> < <?>-<?>(?) <= <?>+<?>(?)>"
599
+ relation_arguments = [actual_float,
600
+ expected_float, delta, expected_float - delta,
601
+ expected_float, delta, expected_float + delta]
602
+ elsif normalized_expected - normalized_delta < normalized_actual
603
+ relation_format = "<<?>-<?>(?) <= <?>+<?>(?) < <?>>"
604
+ relation_arguments = [expected_float, delta, expected_float - delta,
605
+ expected_float, delta, expected_float + delta,
606
+ actual_float]
607
+ end
608
+
609
+ if relation_format
610
+ format << <<-EOT
611
+
612
+ Relation:
613
+ #{relation_format}
541
614
  EOT
542
- assert_block(full_message) { (expected_float.to_f - actual_float.to_f).abs <= delta.to_f }
615
+ arguments.concat(relation_arguments)
543
616
  end
617
+
618
+ build_message(message, format, *arguments)
544
619
  end
620
+ public
621
+ # :startdoc:
545
622
 
546
623
  ##
547
624
  # Passes if the method send returns a true value.
@@ -789,6 +866,90 @@ EOT
789
866
  end
790
867
  end
791
868
 
869
+ ##
870
+ # Passes if +object+#+alias_name+ is an alias method of
871
+ # +object+#+original_name+.
872
+ #
873
+ # Example:
874
+ # assert_alias_method([], :length, :size) # -> pass
875
+ # assert_alias_method([], :size, :length) # -> pass
876
+ # assert_alias_method([], :each, :size) # -> fail
877
+ def assert_alias_method(object, alias_name, original_name, message=nil)
878
+ _wrap_assertion do
879
+ find_method_failure_message = Proc.new do |method_name|
880
+ build_message(message,
881
+ "<?>.? doesn't exist\n" +
882
+ "(Class: <?>)",
883
+ object,
884
+ AssertionMessage.literal(method_name),
885
+ object.class)
886
+ end
887
+
888
+ alias_method = original_method = nil
889
+ assert_block(find_method_failure_message.call(alias_name)) do
890
+ begin
891
+ alias_method = object.method(alias_name)
892
+ true
893
+ rescue NameError
894
+ false
895
+ end
896
+ end
897
+ assert_block(find_method_failure_message.call(original_name)) do
898
+ begin
899
+ original_method = object.method(original_name)
900
+ true
901
+ rescue NameError
902
+ false
903
+ end
904
+ end
905
+
906
+ full_message = build_message(message,
907
+ "<?> is alias of\n" +
908
+ "<?> expected",
909
+ alias_method,
910
+ original_method)
911
+ assert_block(full_message) do
912
+ alias_method == original_method
913
+ end
914
+ end
915
+ end
916
+
917
+ ##
918
+ # Passes if +path+ exists.
919
+ #
920
+ # Example:
921
+ # assert_path_exist("/tmp") # -> pass
922
+ # assert_path_exist("/bin/sh") # -> pass
923
+ # assert_path_exist("/nonexistent") # -> fail
924
+ def assert_path_exist(path, message=nil)
925
+ _wrap_assertion do
926
+ failure_message = build_message(message,
927
+ "<?> expected to exist",
928
+ path)
929
+ assert_block(failure_message) do
930
+ File.exist?(path)
931
+ end
932
+ end
933
+ end
934
+
935
+ ##
936
+ # Passes if +path+ doesn't exist.
937
+ #
938
+ # Example:
939
+ # assert_path_not_exist("/nonexistent") # -> pass
940
+ # assert_path_not_exist("/tmp") # -> fail
941
+ # assert_path_not_exist("/bin/sh") # -> fail
942
+ def assert_path_not_exist(path, message=nil)
943
+ _wrap_assertion do
944
+ failure_message = build_message(message,
945
+ "<?> expected to not exist",
946
+ path)
947
+ assert_block(failure_message) do
948
+ not File.exist?(path)
949
+ end
950
+ end
951
+ end
952
+
792
953
  ##
793
954
  # Builds a failure message. +head+ is added before the +template+ and
794
955
  # +arguments+ replaces the '?'s positionally in the template.
@@ -881,23 +1042,44 @@ EOT
881
1042
  end
882
1043
 
883
1044
  MAX_DIFF_TARGET_STRING_SIZE = 1000
1045
+ def max_diff_target_string_size
1046
+ size = ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"]
1047
+ if size
1048
+ begin
1049
+ size = Integer(size)
1050
+ rescue ArgumentError
1051
+ size = nil
1052
+ end
1053
+ end
1054
+ size || MAX_DIFF_TARGET_STRING_SIZE
1055
+ end
1056
+
884
1057
  def diff_target_string?(string)
885
1058
  if string.respond_to?(:bytesize)
886
- string.bytesize < MAX_DIFF_TARGET_STRING_SIZE
1059
+ string.bytesize < max_diff_target_string_size
887
1060
  else
888
- string.size < MAX_DIFF_TARGET_STRING_SIZE
1061
+ string.size < max_diff_target_string_size
1062
+ end
1063
+ end
1064
+
1065
+ def prepare_for_diff(from, to)
1066
+ if !from.is_a?(String) or !to.is_a?(String)
1067
+ from = convert(from)
1068
+ to = convert(to)
1069
+ end
1070
+
1071
+ if diff_target_string?(from) and diff_target_string?(to)
1072
+ [from, to]
1073
+ else
1074
+ [nil, nil]
889
1075
  end
890
1076
  end
891
1077
 
892
1078
  def delayed_diff(from, to)
893
1079
  delayed_literal do
894
- if !from.is_a?(String) or !to.is_a?(String)
895
- from = convert(from)
896
- to = convert(to)
897
- end
1080
+ from, to = prepare_for_diff(from, to)
898
1081
 
899
- diff = nil
900
- diff = "" if !diff_target_string?(from) or !diff_target_string?(to)
1082
+ diff = "" if from.nil? or to.nil?
901
1083
  diff ||= Diff.readable(from, to)
902
1084
  if /^[-+]/ !~ diff
903
1085
  diff = ""
@@ -7,6 +7,7 @@ module Test
7
7
  RUNNERS = {}
8
8
  COLLECTORS = {}
9
9
  ADDITIONAL_OPTIONS = []
10
+ PREPARE_HOOKS = []
10
11
 
11
12
  class << self
12
13
  def register_runner(id, runner_builder=Proc.new)
@@ -18,6 +19,15 @@ module Test
18
19
  RUNNERS[id.to_s]
19
20
  end
20
21
 
22
+ @@default_runner = nil
23
+ def default_runner
24
+ runner(@@default_runner)
25
+ end
26
+
27
+ def default_runner=(id)
28
+ @@default_runner = id
29
+ end
30
+
21
31
  def register_collector(id, collector_builder=Proc.new)
22
32
  COLLECTORS[id] = collector_builder
23
33
  COLLECTORS[id.to_s] = collector_builder
@@ -34,15 +44,20 @@ module Test
34
44
  def setup_option(option_builder=Proc.new)
35
45
  ADDITIONAL_OPTIONS << option_builder
36
46
  end
47
+
48
+ def prepare(hook=Proc.new)
49
+ PREPARE_HOOKS << hook
50
+ end
37
51
  end
38
52
 
39
53
  def self.run(force_standalone=false, default_dir=nil, argv=ARGV, &block)
40
54
  r = new(force_standalone || standalone?, &block)
41
55
  r.base = default_dir
56
+ r.prepare
42
57
  r.process_args(argv)
43
58
  r.run
44
59
  end
45
-
60
+
46
61
  def self.standalone?
47
62
  return false unless("-e" == $0)
48
63
  ObjectSpace.each_object(Class) do |klass|
@@ -90,7 +105,7 @@ module Test
90
105
 
91
106
  attr_reader :suite, :runner_options
92
107
  attr_accessor :filters, :to_run, :pattern, :exclude, :base, :workdir
93
- attr_accessor :color_scheme
108
+ attr_accessor :color_scheme, :listeners
94
109
  attr_writer :runner, :collector
95
110
 
96
111
  def initialize(standalone)
@@ -104,31 +119,32 @@ module Test
104
119
  @runner_options = {}
105
120
  @default_arguments = []
106
121
  @workdir = nil
122
+ @listeners = []
107
123
  config_file = "test-unit.yml"
108
124
  if File.exist?(config_file)
109
125
  load_config(config_file)
110
126
  else
111
- global_config_file = File.expand_path("~/.test-unit.xml")
112
- load_config(global_config_file) if File.exist?(global_config_file)
127
+ load_global_config
113
128
  end
114
129
  yield(self) if block_given?
115
130
  end
116
131
 
132
+ def prepare
133
+ PREPARE_HOOKS.each do |handler|
134
+ handler.call(self)
135
+ end
136
+ end
137
+
117
138
  def process_args(args = ARGV)
118
- default_arguments = @default_arguments.dup
119
139
  begin
120
- @default_arguments.concat(args)
121
- options.order!(@default_arguments) {|arg| @to_run << arg}
140
+ args.unshift(*@default_arguments)
141
+ options.order!(args) {|arg| @to_run << arg}
122
142
  rescue OptionParser::ParseError => e
123
143
  puts e
124
144
  puts options
125
145
  exit(false)
126
- else
127
- @filters << proc{false} unless(@filters.empty?)
128
146
  end
129
147
  not @to_run.empty?
130
- ensure
131
- @default_arguments = default_arguments
132
148
  end
133
149
 
134
150
  def options
@@ -177,9 +193,9 @@ module Test
177
193
  n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
178
194
  case n
179
195
  when Regexp
180
- @filters << proc{|t| n =~ t.method_name ? true : nil}
196
+ @filters << proc{|t| n =~ t.method_name ? true : false}
181
197
  else
182
- @filters << proc{|t| n == t.method_name ? true : nil}
198
+ @filters << proc{|t| n == t.method_name}
183
199
  end
184
200
  end
185
201
 
@@ -189,17 +205,17 @@ module Test
189
205
  n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
190
206
  case n
191
207
  when Regexp
192
- @filters << proc{|t| n =~ t.class.name ? true : nil}
208
+ @filters << proc{|t| n =~ t.class.name ? true : false}
193
209
  else
194
- @filters << proc{|t| n == t.class.name ? true : nil}
210
+ @filters << proc{|t| n == t.class.name}
195
211
  end
196
212
  end
197
213
 
198
214
  priority_filter = Proc.new do |test|
199
- if @filters.size > 2
200
- nil
215
+ if @filters == [priority_filter]
216
+ Priority::Checker.new(test).need_to_run?
201
217
  else
202
- Priority::Checker.new(test).need_to_run? or nil
218
+ nil
203
219
  end
204
220
  end
205
221
  o.on("--[no-]priority-mode",
@@ -297,6 +313,8 @@ module Test
297
313
  runner = @runner[self]
298
314
  return false if runner.nil?
299
315
  @runner_options[:color_scheme] ||= @color_scheme
316
+ @runner_options[:listeners] ||= []
317
+ @runner_options[:listeners].concat(@listeners)
300
318
  Dir.chdir(@workdir) if @workdir
301
319
  runner.run(suite, @runner_options).passed?
302
320
  end
@@ -325,16 +343,29 @@ module Test
325
343
 
326
344
  private
327
345
  def default_runner
346
+ runner = self.class.default_runner
328
347
  if ENV["EMACS"] == "t"
329
- self.class.runner(:emacs)
348
+ runner ||= self.class.runner(:emacs)
330
349
  else
331
- self.class.runner(:console)
350
+ runner ||= self.class.runner(:console)
332
351
  end
352
+ runner
333
353
  end
334
354
 
335
355
  def default_collector
336
356
  self.class.collector(@standalone ? :load : :descendant)
337
357
  end
358
+
359
+ def global_config_file
360
+ File.expand_path("~/.test-unit.yml")
361
+ rescue ArgumentError
362
+ nil
363
+ end
364
+
365
+ def load_global_config
366
+ file = global_config_file
367
+ load_config(file) if file and File.exist?(file)
368
+ end
338
369
  end
339
370
  end
340
371
  end