groonga 0.0.7 → 0.9.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 (102) hide show
  1. data/NEWS.ja.rdoc +56 -0
  2. data/NEWS.rdoc +58 -0
  3. data/Rakefile +2 -3
  4. data/benchmark/read-write-many-small-items.rb +16 -32
  5. data/benchmark/write-many-small-items.rb +14 -28
  6. data/example/bookmark.rb +19 -17
  7. data/example/index-html.rb +11 -1
  8. data/example/search/config.ru +14 -9
  9. data/ext/rb-grn-array.c +6 -6
  10. data/ext/rb-grn-column.c +348 -18
  11. data/ext/rb-grn-context.c +8 -4
  12. data/ext/rb-grn-database.c +6 -7
  13. data/ext/rb-grn-exception.c +101 -5
  14. data/ext/rb-grn-expression.c +206 -23
  15. data/ext/rb-grn-fix-size-column.c +6 -39
  16. data/ext/rb-grn-hash.c +24 -24
  17. data/ext/rb-grn-index-column.c +74 -19
  18. data/ext/rb-grn-logger.c +48 -0
  19. data/ext/rb-grn-object.c +281 -67
  20. data/ext/rb-grn-operation.c +1 -1
  21. data/ext/rb-grn-patricia-trie-cursor.c +10 -1
  22. data/ext/rb-grn-patricia-trie.c +268 -7
  23. data/ext/rb-grn-query.c +52 -1
  24. data/ext/rb-grn-record.c +8 -2
  25. data/ext/rb-grn-snippet.c +63 -1
  26. data/ext/rb-grn-table-cursor-key-support.c +15 -1
  27. data/ext/rb-grn-table-cursor.c +57 -0
  28. data/ext/rb-grn-table-key-support.c +382 -46
  29. data/ext/rb-grn-table.c +729 -192
  30. data/ext/rb-grn-type.c +63 -12
  31. data/ext/rb-grn-utils.c +156 -158
  32. data/ext/rb-grn-variable.c +18 -0
  33. data/ext/rb-grn.h +85 -21
  34. data/ext/rb-groonga.c +13 -3
  35. data/extconf.rb +19 -4
  36. data/html/developer.html +1 -1
  37. data/html/header.html.erb +1 -1
  38. data/html/index.html +4 -4
  39. data/lib/groonga.rb +10 -0
  40. data/lib/groonga/expression-builder.rb +81 -42
  41. data/lib/groonga/patricia-trie.rb +13 -0
  42. data/lib/groonga/record.rb +158 -13
  43. data/lib/groonga/schema.rb +339 -33
  44. data/pkg-config.rb +6 -1
  45. data/test-unit/lib/test/unit.rb +23 -42
  46. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  47. data/test-unit/lib/test/unit/assertions.rb +87 -9
  48. data/test-unit/lib/test/unit/autorunner.rb +20 -11
  49. data/test-unit/lib/test/unit/collector.rb +1 -8
  50. data/test-unit/lib/test/unit/collector/load.rb +2 -3
  51. data/test-unit/lib/test/unit/color-scheme.rb +13 -1
  52. data/test-unit/lib/test/unit/diff.rb +223 -37
  53. data/test-unit/lib/test/unit/error.rb +4 -0
  54. data/test-unit/lib/test/unit/failure.rb +31 -5
  55. data/test-unit/lib/test/unit/notification.rb +8 -4
  56. data/test-unit/lib/test/unit/omission.rb +51 -3
  57. data/test-unit/lib/test/unit/pending.rb +4 -0
  58. data/test-unit/lib/test/unit/testcase.rb +55 -4
  59. data/test-unit/lib/test/unit/ui/console/testrunner.rb +190 -4
  60. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  61. data/test-unit/lib/test/unit/ui/testrunner.rb +8 -0
  62. data/test-unit/lib/test/unit/version.rb +1 -1
  63. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  64. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  65. data/test-unit/sample/test_user.rb +1 -0
  66. data/test-unit/test/collector/test-descendant.rb +2 -4
  67. data/test-unit/test/collector/test_objectspace.rb +7 -5
  68. data/test-unit/test/run-test.rb +2 -0
  69. data/test-unit/test/test-color-scheme.rb +7 -0
  70. data/test-unit/test/test-diff.rb +48 -7
  71. data/test-unit/test/test-omission.rb +1 -1
  72. data/test-unit/test/test-testcase.rb +47 -0
  73. data/test-unit/test/test_assertions.rb +79 -10
  74. data/test/groonga-test-utils.rb +6 -1
  75. data/test/test-array.rb +29 -14
  76. data/test/test-column.rb +107 -55
  77. data/test/test-context.rb +5 -0
  78. data/test/test-database.rb +2 -37
  79. data/test/test-exception.rb +9 -1
  80. data/test/test-expression-builder.rb +23 -5
  81. data/test/test-expression.rb +44 -8
  82. data/test/test-fix-size-column.rb +16 -5
  83. data/test/test-gqtp.rb +70 -0
  84. data/test/test-hash.rb +142 -43
  85. data/test/test-index-column.rb +9 -9
  86. data/test/test-patricia-trie.rb +79 -20
  87. data/test/test-procedure.rb +4 -2
  88. data/test/test-record.rb +32 -20
  89. data/test/test-remote.rb +3 -2
  90. data/test/test-schema.rb +226 -92
  91. data/test/test-table-cursor.rb +103 -1
  92. data/test/test-table-offset-and-limit.rb +102 -0
  93. data/test/test-table-select-normalize.rb +4 -4
  94. data/test/test-table-select.rb +52 -8
  95. data/test/test-table.rb +235 -116
  96. data/test/test-type.rb +2 -2
  97. data/test/test-variable-size-column.rb +21 -5
  98. data/test/test-vector-column.rb +76 -0
  99. data/{TUTORIAL.ja.rdoc → text/TUTORIAL.ja.rdoc} +52 -52
  100. data/text/expression.rdoc +284 -0
  101. metadata +11 -7
  102. data/test-unit/sample/ts_examples.rb +0 -7
@@ -60,6 +60,10 @@ module Test
60
60
  def to_s
61
61
  long_display
62
62
  end
63
+
64
+ def critical?
65
+ true
66
+ end
63
67
  end
64
68
 
65
69
  module ErrorHandler
@@ -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(:handle_Notified_error)
86
+ base.exception_handler(:handle_notified_error)
83
87
  end
84
88
  end
85
89
 
86
90
  private
87
- def handle_Notified_error(exception)
91
+ def handle_notified_error(exception)
88
92
  return false unless exception.is_a?(NotifiedError)
89
93
  notification = Notification.new(name,
90
- filter_backtrace(exception.backtrace),
91
- exception.message)
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 of part of 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
- omit(*args, &block) if condition
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
- omit(*args, &block) unless condition
132
+ if condition
133
+ block.call if block
134
+ else
135
+ omit(*args, &block)
136
+ end
89
137
  end
90
138
 
91
139
  private
@@ -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 PendedError < StandardError
@@ -94,10 +94,15 @@ module Test
94
94
  DESCENDANTS << sub_class
95
95
  end
96
96
 
97
- @@added_methods = []
97
+ @@added_methods = {}
98
98
  def method_added(name) # :nodoc:
99
99
  super
100
- @@added_methods << name.to_s
100
+ added_methods = (@@added_methods[self] ||= [])
101
+ stringified_name = name.to_s
102
+ if added_methods.include?(stringified_name)
103
+ attribute(:redefined, true, {}, stringified_name)
104
+ end
105
+ added_methods << stringified_name
101
106
  end
102
107
 
103
108
  # Rolls up all of the test* methods in the fixture into
@@ -212,6 +217,39 @@ module Test
212
217
  @@test_order = order
213
218
  end
214
219
 
220
+ # Defines a test in declarative syntax.
221
+ #
222
+ # The following two test definitions are the same:
223
+ #
224
+ # description "register user"
225
+ # def test_register_user
226
+ # ...
227
+ # end
228
+ #
229
+ # test "register user" do
230
+ # ...
231
+ # end
232
+ def test(test_description, &block)
233
+ normalized_description = test_description.gsub(/[^a-zA-Z\d_]+/, '_')
234
+ method_name = "test_#{normalized_description}".to_sym
235
+ define_method(method_name, &block)
236
+ description(test_description, method_name)
237
+ end
238
+
239
+ # Describes a test.
240
+ #
241
+ # The following example associates "register a
242
+ # normal user" description with "test_register"
243
+ # test.
244
+ #
245
+ # description "register a normal user"
246
+ # def test_register
247
+ # ...
248
+ # end
249
+ def description(value, target=nil)
250
+ attribute(:description, value, {}, target || [])
251
+ end
252
+
215
253
  # :stopdoc:
216
254
  private
217
255
  def collect_test_names
@@ -233,9 +271,10 @@ module Test
233
271
  end
234
272
 
235
273
  def sort_test_names_in_defined_order(test_names)
274
+ added_methods = @@added_methods[self]
236
275
  test_names.sort do |test1, test2|
237
- test1_defined_order = @@added_methods.index(test1)
238
- test2_defined_order = @@added_methods.index(test2)
276
+ test1_defined_order = added_methods.index(test1)
277
+ test2_defined_order = added_methods.index(test2)
239
278
  if test1_defined_order and test2_defined_order
240
279
  test1_defined_order <=> test2_defined_order
241
280
  elsif test1_defined_order
@@ -374,6 +413,15 @@ module Test
374
413
  "#{@method_name}(#{self.class.name})"
375
414
  end
376
415
 
416
+ # Returns a description for the test. A description
417
+ # will be associated by Test::Unit::TestCase.test or
418
+ # Test::Unit::TestCase.description.
419
+ #
420
+ # Returns a name for the test for no description test.
421
+ def description
422
+ self[:description] || name
423
+ end
424
+
377
425
  # Overridden to return #name.
378
426
  def to_s
379
427
  name
@@ -396,6 +444,9 @@ module Test
396
444
  end
397
445
 
398
446
  def run_test
447
+ if self.class.get_attribute(@method_name, :redefined)
448
+ notify("#{self.class}\##{@method_name} was redefined")
449
+ end
399
450
  __send__(@method_name)
400
451
  end
401
452
 
@@ -84,7 +84,7 @@ module Test
84
84
  def add_fault(fault)
85
85
  @faults << fault
86
86
  output_progress(fault.single_character_display, fault_color(fault))
87
- @already_outputted = true
87
+ @already_outputted = true if fault.critical?
88
88
  end
89
89
 
90
90
  def started(result)
@@ -101,9 +101,7 @@ module Test
101
101
  @faults.each_with_index do |fault, index|
102
102
  nl
103
103
  output_single("%3d) " % (index + 1))
104
- label, detail = format_fault(fault).split(/\r?\n/, 2)
105
- output(label, fault_color(fault))
106
- output(detail)
104
+ output_fault(fault)
107
105
  end
108
106
  nl
109
107
  output("Finished in #{elapsed_time} seconds.")
@@ -118,6 +116,65 @@ module Test
118
116
  output("%g%% passed" % pass_percentage, result_color)
119
117
  end
120
118
 
119
+ def output_fault(fault)
120
+ if @use_color and fault.is_a?(Failure) and
121
+ fault.inspected_expected and fault.inspected_actual
122
+ output_single(fault.label, fault_color(fault))
123
+ output(":")
124
+ output_fault_backtrace(fault)
125
+ output_fault_message(fault)
126
+ else
127
+ label, detail = format_fault(fault).split(/\r?\n/, 2)
128
+ output(label, fault_color(fault))
129
+ output(detail)
130
+ end
131
+ end
132
+
133
+ def output_fault_backtrace(fault)
134
+ backtrace = fault.location
135
+ if backtrace.size == 1
136
+ output(fault.test_name +
137
+ backtrace[0].sub(/\A(.+:\d+).*/, ' [\\1]') +
138
+ ":")
139
+ else
140
+ output(fault.test_name)
141
+ backtrace.each_with_index do |entry, i|
142
+ if i.zero?
143
+ prefix = "["
144
+ postfix = ""
145
+ elsif i == backtrace.size - 1
146
+ prefix = " "
147
+ postfix = "]:"
148
+ else
149
+ prefix = " "
150
+ postfix = ""
151
+ end
152
+ output(" #{prefix}#{entry}#{postfix}")
153
+ end
154
+ end
155
+ end
156
+
157
+ def output_fault_message(fault)
158
+ output(fault.user_message) if fault.user_message
159
+ output_single("<")
160
+ output_single(fault.inspected_expected, color("success"))
161
+ output("> expected but was")
162
+ output_single("<")
163
+ output_single(fault.inspected_actual, color("failure"))
164
+ output(">")
165
+ from, to = prepare_for_diff(fault.expected, fault.actual)
166
+ if from and to
167
+ differ = ColorizedReadableDiffer.new(from.split(/\r?\n/),
168
+ to.split(/\r?\n/),
169
+ self)
170
+ if differ.need_diff?
171
+ output("")
172
+ output("diff:")
173
+ differ.diff
174
+ end
175
+ end
176
+ end
177
+
121
178
  def format_fault(fault)
122
179
  fault.long_display
123
180
  end
@@ -268,6 +325,135 @@ module Test
268
325
  0
269
326
  end
270
327
  end
328
+
329
+ class ColorizedReadableDiffer < Diff::ReadableDiffer
330
+ def initialize(from, to, runner)
331
+ @runner = runner
332
+ super(from, to)
333
+ end
334
+
335
+ def need_diff?(options={})
336
+ operations.each do |tag,|
337
+ return true if [:replace, :equal].include?(tag)
338
+ end
339
+ false
340
+ end
341
+
342
+ private
343
+ def output_single(something, color=nil)
344
+ @runner.send(:output_single, something, color)
345
+ end
346
+
347
+ def output(something, color=nil)
348
+ @runner.send(:output, something, color)
349
+ end
350
+
351
+ def color(name)
352
+ @runner.send(:color, name)
353
+ end
354
+
355
+ def cut_off_ratio
356
+ 0
357
+ end
358
+
359
+ def default_ratio
360
+ 0
361
+ end
362
+
363
+ def tag(mark, color_name, contents)
364
+ _color = color(color_name)
365
+ contents.each do |content|
366
+ output_single(mark, _color)
367
+ output_single(" ")
368
+ output(content)
369
+ end
370
+ end
371
+
372
+ def tag_deleted(contents)
373
+ tag("-", "diff-deleted-tag", contents)
374
+ end
375
+
376
+ def tag_inserted(contents)
377
+ tag("+", "diff-inserted-tag", contents)
378
+ end
379
+
380
+ def tag_equal(contents)
381
+ tag(" ", "normal", contents)
382
+ end
383
+
384
+ def tag_difference(contents)
385
+ tag("?", "diff-difference-tag", contents)
386
+ end
387
+
388
+ def diff_line(from_line, to_line)
389
+ to_operations = []
390
+ from_line, to_line, _operations = line_operations(from_line, to_line)
391
+
392
+ no_replace = true
393
+ _operations.each do |tag,|
394
+ if tag == :replace
395
+ no_replace = false
396
+ break
397
+ end
398
+ end
399
+
400
+ output_single("?", color("diff-difference-tag"))
401
+ output_single(" ")
402
+ _operations.each do |tag, from_start, from_end, to_start, to_end|
403
+ from_width = compute_width(from_line, from_start, from_end)
404
+ to_width = compute_width(to_line, to_start, to_end)
405
+ case tag
406
+ when :replace
407
+ output_single(from_line[from_start...from_end],
408
+ color("diff-deleted"))
409
+ if (from_width < to_width)
410
+ output_single(" " * (to_width - from_width))
411
+ end
412
+ to_operations << Proc.new do
413
+ output_single(to_line[to_start...to_end],
414
+ color("diff-inserted"))
415
+ if (to_width < from_width)
416
+ output_single(" " * (from_width - to_width))
417
+ end
418
+ end
419
+ when :delete
420
+ output_single(from_line[from_start...from_end],
421
+ color("diff-deleted"))
422
+ unless no_replace
423
+ to_operations << Proc.new {output_single(" " * from_width)}
424
+ end
425
+ when :insert
426
+ if no_replace
427
+ output_single(to_line[to_start...to_end],
428
+ color("diff-inserted"))
429
+ else
430
+ output_single(" " * to_width)
431
+ to_operations << Proc.new do
432
+ output_single(to_line[to_start...to_end],
433
+ color("diff-inserted"))
434
+ end
435
+ end
436
+ when :equal
437
+ output_single(from_line[from_start...from_end])
438
+ unless no_replace
439
+ to_operations << Proc.new {output_single(" " * to_width)}
440
+ end
441
+ else
442
+ raise "unknown tag: #{tag}"
443
+ end
444
+ end
445
+ output("")
446
+
447
+ unless to_operations.empty?
448
+ output_single("?", color("diff-difference-tag"))
449
+ output_single(" ")
450
+ to_operations.each do |operation|
451
+ operation.call
452
+ end
453
+ output("")
454
+ end
455
+ end
456
+ end
271
457
  end
272
458
  end
273
459
  end