activegroonga 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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