rroonga 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. data/README.textile +71 -0
  2. data/Rakefile +213 -128
  3. data/TODO +0 -0
  4. data/example/bookmark.rb +12 -12
  5. data/ext/groonga/Makefile +233 -0
  6. data/ext/groonga/extconf.rb +1 -1
  7. data/ext/groonga/rb-grn-column.c +5 -5
  8. data/ext/groonga/rb-grn-index-column.c +31 -0
  9. data/ext/groonga/rb-grn-index-cursor.c +106 -0
  10. data/ext/groonga/rb-grn-logger.c +5 -5
  11. data/ext/groonga/rb-grn-object.c +48 -0
  12. data/ext/groonga/rb-grn-patricia-trie.c +1 -1
  13. data/ext/groonga/rb-grn-plugin.c +32 -0
  14. data/ext/groonga/rb-grn-posting.c +51 -0
  15. data/ext/groonga/rb-grn-table-cursor.c +6 -1
  16. data/ext/groonga/rb-grn-table.c +31 -13
  17. data/ext/groonga/rb-grn.h +21 -3
  18. data/ext/groonga/rb-groonga.c +3 -1
  19. data/lib/groonga.rb +1 -0
  20. data/lib/groonga/dumper.rb +25 -5
  21. data/lib/groonga/expression-builder.rb +2 -2
  22. data/lib/groonga/pagination.rb +99 -7
  23. data/lib/groonga/posting.rb +87 -0
  24. data/lib/groonga/record.rb +118 -11
  25. data/lib/groonga/schema.rb +18 -1
  26. data/test/groonga-test-utils.rb +1 -6
  27. data/test/run-test.rb +13 -28
  28. data/test/test-column.rb +4 -0
  29. data/test/test-database-dumper.rb +53 -10
  30. data/test/test-hash.rb +6 -6
  31. data/test/test-index-cursor.rb +93 -0
  32. data/test/test-plugin.rb +6 -0
  33. data/test/test-record.rb +162 -1
  34. data/test/test-schema-type.rb +6 -0
  35. data/test/test-schema.rb +17 -0
  36. data/test/test-table.rb +7 -2
  37. data/test/test-type.rb +9 -1
  38. metadata +135 -245
  39. data/AUTHORS +0 -5
  40. data/NEWS.ja.rdoc +0 -344
  41. data/NEWS.rdoc +0 -346
  42. data/README.ja.rdoc +0 -68
  43. data/README.rdoc +0 -68
  44. data/example/search/config.ru +0 -230
  45. data/example/search/public/css/groonga.css +0 -122
  46. data/ext/.gitignore +0 -2
  47. data/html/bar.svg +0 -153
  48. data/html/developer.html +0 -151
  49. data/html/developer.svg +0 -469
  50. data/html/download.svg +0 -253
  51. data/html/favicon.ico +0 -0
  52. data/html/favicon.svg +0 -591
  53. data/html/footer.html.erb +0 -33
  54. data/html/head.html.erb +0 -4
  55. data/html/header.html.erb +0 -17
  56. data/html/heading-mark.svg +0 -393
  57. data/html/index.html +0 -243
  58. data/html/install.svg +0 -636
  59. data/html/logo.svg +0 -612
  60. data/html/ranguba.css +0 -342
  61. data/html/readme.svg +0 -256
  62. data/html/tutorial.svg +0 -559
  63. data/license/LGPL +0 -504
  64. data/test-unit-notify/Rakefile +0 -47
  65. data/test-unit-notify/lib/test/unit/notify.rb +0 -104
  66. data/test-unit/COPYING +0 -56
  67. data/test-unit/GPL +0 -340
  68. data/test-unit/PSFL +0 -271
  69. data/test-unit/Rakefile +0 -53
  70. data/test-unit/TODO +0 -5
  71. data/test-unit/bin/testrb +0 -5
  72. data/test-unit/html/bar.svg +0 -153
  73. data/test-unit/html/developer.svg +0 -469
  74. data/test-unit/html/favicon.ico +0 -0
  75. data/test-unit/html/favicon.svg +0 -82
  76. data/test-unit/html/heading-mark.svg +0 -393
  77. data/test-unit/html/index.html +0 -247
  78. data/test-unit/html/index.html.ja +0 -270
  79. data/test-unit/html/install.svg +0 -636
  80. data/test-unit/html/logo.svg +0 -483
  81. data/test-unit/html/test-unit.css +0 -339
  82. data/test-unit/html/tutorial.svg +0 -559
  83. data/test-unit/lib/test/unit.rb +0 -328
  84. data/test-unit/lib/test/unit/assertionfailederror.rb +0 -25
  85. data/test-unit/lib/test/unit/assertions.rb +0 -1334
  86. data/test-unit/lib/test/unit/attribute.rb +0 -125
  87. data/test-unit/lib/test/unit/autorunner.rb +0 -363
  88. data/test-unit/lib/test/unit/collector.rb +0 -36
  89. data/test-unit/lib/test/unit/collector/descendant.rb +0 -23
  90. data/test-unit/lib/test/unit/collector/dir.rb +0 -108
  91. data/test-unit/lib/test/unit/collector/load.rb +0 -144
  92. data/test-unit/lib/test/unit/collector/objectspace.rb +0 -34
  93. data/test-unit/lib/test/unit/color-scheme.rb +0 -106
  94. data/test-unit/lib/test/unit/color.rb +0 -96
  95. data/test-unit/lib/test/unit/diff.rb +0 -740
  96. data/test-unit/lib/test/unit/error.rb +0 -130
  97. data/test-unit/lib/test/unit/exceptionhandler.rb +0 -39
  98. data/test-unit/lib/test/unit/failure.rb +0 -136
  99. data/test-unit/lib/test/unit/fixture.rb +0 -176
  100. data/test-unit/lib/test/unit/notification.rb +0 -129
  101. data/test-unit/lib/test/unit/omission.rb +0 -191
  102. data/test-unit/lib/test/unit/pending.rb +0 -150
  103. data/test-unit/lib/test/unit/priority.rb +0 -180
  104. data/test-unit/lib/test/unit/runner/console.rb +0 -52
  105. data/test-unit/lib/test/unit/runner/emacs.rb +0 -8
  106. data/test-unit/lib/test/unit/runner/tap.rb +0 -8
  107. data/test-unit/lib/test/unit/testcase.rb +0 -483
  108. data/test-unit/lib/test/unit/testresult.rb +0 -121
  109. data/test-unit/lib/test/unit/testsuite.rb +0 -110
  110. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +0 -14
  111. data/test-unit/lib/test/unit/ui/console/testrunner.rb +0 -430
  112. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +0 -63
  113. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +0 -82
  114. data/test-unit/lib/test/unit/ui/testrunner.rb +0 -53
  115. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +0 -77
  116. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +0 -41
  117. data/test-unit/lib/test/unit/util/backtracefilter.rb +0 -42
  118. data/test-unit/lib/test/unit/util/method-owner-finder.rb +0 -28
  119. data/test-unit/lib/test/unit/util/observable.rb +0 -90
  120. data/test-unit/lib/test/unit/util/output.rb +0 -31
  121. data/test-unit/lib/test/unit/util/procwrapper.rb +0 -48
  122. data/test-unit/lib/test/unit/version.rb +0 -7
  123. data/test-unit/sample/adder.rb +0 -13
  124. data/test-unit/sample/subtracter.rb +0 -12
  125. data/test-unit/sample/test_adder.rb +0 -20
  126. data/test-unit/sample/test_subtracter.rb +0 -20
  127. data/test-unit/sample/test_user.rb +0 -23
  128. data/test-unit/test/collector/test-descendant.rb +0 -133
  129. data/test-unit/test/collector/test-load.rb +0 -442
  130. data/test-unit/test/collector/test_dir.rb +0 -406
  131. data/test-unit/test/collector/test_objectspace.rb +0 -100
  132. data/test-unit/test/run-test.rb +0 -15
  133. data/test-unit/test/test-attribute.rb +0 -86
  134. data/test-unit/test/test-color-scheme.rb +0 -69
  135. data/test-unit/test/test-color.rb +0 -47
  136. data/test-unit/test/test-diff.rb +0 -518
  137. data/test-unit/test/test-emacs-runner.rb +0 -60
  138. data/test-unit/test/test-fixture.rb +0 -287
  139. data/test-unit/test/test-notification.rb +0 -33
  140. data/test-unit/test/test-omission.rb +0 -81
  141. data/test-unit/test/test-pending.rb +0 -70
  142. data/test-unit/test/test-priority.rb +0 -119
  143. data/test-unit/test/test-testcase.rb +0 -544
  144. data/test-unit/test/test_assertions.rb +0 -1197
  145. data/test-unit/test/test_error.rb +0 -26
  146. data/test-unit/test/test_failure.rb +0 -33
  147. data/test-unit/test/test_testresult.rb +0 -113
  148. data/test-unit/test/test_testsuite.rb +0 -129
  149. data/test-unit/test/testunit-test-util.rb +0 -14
  150. data/test-unit/test/ui/test_tap.rb +0 -33
  151. data/test-unit/test/ui/test_testrunmediator.rb +0 -20
  152. data/test-unit/test/util/test-method-owner-finder.rb +0 -38
  153. data/test-unit/test/util/test-output.rb +0 -11
  154. data/test-unit/test/util/test_backtracefilter.rb +0 -41
  155. data/test-unit/test/util/test_observable.rb +0 -102
  156. data/test-unit/test/util/test_procwrapper.rb +0 -36
  157. data/test/.gitignore +0 -1
  158. data/text/expression.rdoc +0 -285
  159. data/text/tutorial.ja.rdoc +0 -433
@@ -18,12 +18,7 @@ require 'pathname'
18
18
  require 'time'
19
19
  require 'erb'
20
20
  require 'stringio'
21
- begin
22
- require 'json'
23
- rescue LoadError
24
- require 'rubygems'
25
- require 'json'
26
- end
21
+ require 'json'
27
22
  require 'pkg-config'
28
23
 
29
24
  require 'groonga'
@@ -20,44 +20,27 @@ $VERBOSE = true
20
20
  $KCODE = "u" if RUBY_VERSION < "1.9"
21
21
 
22
22
  base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
23
- test_unit_dir = File.join(base_dir, "test-unit")
24
- test_unit_lib_dir = File.join(test_unit_dir, "lib")
25
- test_unit_notify_dir = File.join(base_dir, "test-unit-notify")
26
- test_unit_notify_lib_dir = File.join(test_unit_notify_dir, "lib")
27
23
  ext_dir = File.join(base_dir, "ext", "groonga")
28
24
  lib_dir = File.join(base_dir, "lib")
29
25
  test_dir = File.join(base_dir, "test")
30
26
 
31
27
  make = nil
32
- if system("which gmake > /dev/null")
33
- make = "gmake"
34
- elsif system("which make > /dev/null")
35
- make = "make"
28
+ if ENV["NO_MAKE"] != "yes"
29
+ if system("which gmake > /dev/null")
30
+ make = "gmake"
31
+ elsif system("which make > /dev/null")
32
+ make = "make"
33
+ end
36
34
  end
37
35
  if make
38
36
  system("cd #{base_dir.dump} && #{make} > /dev/null") or exit(false)
39
37
  end
40
38
 
41
- test_unit_repository_base = "http://test-unit.rubyforge.org/svn/"
42
- unless File.exist?(test_unit_dir)
43
- test_unit_repository = "#{test_unit_repository_base}trunk/"
44
- system("svn", "co", test_unit_repository, test_unit_dir) or exit(false)
45
- end
46
-
47
- unless File.exist?(test_unit_notify_dir)
48
- test_unit_notify_repository = "#{test_unit_repository_base}/extensions/test-unit-notify/trunk/"
49
- system("svn", "co", test_unit_notify_repository, test_unit_notify_dir) or exit(false)
50
- system("svn", "up", test_unit_dir) or exit(false)
51
- end
39
+ require "rubygems"
40
+ gem "test-unit-notify"
41
+ require "test/unit/notify"
52
42
 
53
- $LOAD_PATH.unshift(test_unit_lib_dir)
54
- $LOAD_PATH.unshift(test_unit_notify_lib_dir)
55
-
56
- require 'test/unit'
57
- require 'test/unit/notify'
58
-
59
- ARGV.unshift("--priority-mode")
60
- ARGV.unshift("--notify")
43
+ Test::Unit::Priority.enable
61
44
 
62
45
  $LOAD_PATH.unshift(ext_dir)
63
46
  $LOAD_PATH.unshift(lib_dir)
@@ -73,4 +56,6 @@ Dir.glob("#{base_dir}/test/**/test{_,-}*.rb") do |file|
73
56
  require file.sub(/\.rb$/, '')
74
57
  end
75
58
 
76
- exit Test::Unit::AutoRunner.run(false)
59
+ ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] ||= "5000"
60
+
61
+ exit Test::Unit::AutoRunner.run
@@ -316,6 +316,10 @@ class ColumnTest < Test::Unit::TestCase
316
316
  title.indexes)
317
317
  end
318
318
 
319
+ def test_builtin?
320
+ assert_not_predicate(@users_name_column, :builtin?)
321
+ end
322
+
319
323
  private
320
324
  def assert_content_search(expected_records, term)
321
325
  records = @bookmarks_index_content.search(term).records
@@ -21,6 +21,13 @@ class DatabaseDumperTest < Test::Unit::TestCase
21
21
  setup
22
22
  def setup_tables
23
23
  Groonga::Schema.define do |schema|
24
+ schema.create_table("Tags",
25
+ :type => :hash,
26
+ :key_type => :short_text,
27
+ :default_tokenizer => :delimit) do |table|
28
+ table.text("name")
29
+ end
30
+
24
31
  schema.create_table("Users",
25
32
  :type => :hash,
26
33
  :key_type => "ShortText") do |table|
@@ -32,7 +39,8 @@ class DatabaseDumperTest < Test::Unit::TestCase
32
39
  table.reference("author", "Users")
33
40
  table.integer("rank")
34
41
  table.unsigned_integer("n_goods")
35
- table.text("tags", :type => :vector)
42
+ table.short_text("tag_text")
43
+ table.reference("tags", "Tags", :type => :vector)
36
44
  table.boolean("published")
37
45
  table.time("created_at")
38
46
  end
@@ -40,6 +48,10 @@ class DatabaseDumperTest < Test::Unit::TestCase
40
48
  schema.change_table("Users") do |table|
41
49
  table.index("Posts.author")
42
50
  end
51
+
52
+ schema.change_table("Tags") do |table|
53
+ table.index("Posts.tag_text")
54
+ end
43
55
  end
44
56
  end
45
57
 
@@ -59,13 +71,19 @@ column_create Posts created_at COLUMN_SCALAR Time
59
71
  column_create Posts n_goods COLUMN_SCALAR UInt32
60
72
  column_create Posts published COLUMN_SCALAR Bool
61
73
  column_create Posts rank COLUMN_SCALAR Int32
62
- column_create Posts tags COLUMN_VECTOR Text
74
+ column_create Posts tag_text COLUMN_SCALAR ShortText
63
75
  column_create Posts title COLUMN_SCALAR Text
64
76
 
77
+ table_create Tags TABLE_HASH_KEY --key_type ShortText --default_tokenizer TokenDelimit
78
+ column_create Tags name COLUMN_SCALAR Text
79
+
65
80
  table_create Users TABLE_HASH_KEY --key_type ShortText
66
81
  column_create Users name COLUMN_SCALAR Text
67
82
 
68
83
  column_create Posts author COLUMN_SCALAR Users
84
+ column_create Posts tags COLUMN_VECTOR Tags
85
+
86
+ column_create Tags Posts_tag_text COLUMN_INDEX Posts tag_text
69
87
 
70
88
  column_create Users Posts_author COLUMN_INDEX Posts author
71
89
  EOS
@@ -85,6 +103,7 @@ EOS
85
103
  :n_goods => 4,
86
104
  :published => true,
87
105
  :rank => 10,
106
+ :tag_text => "search mori",
88
107
  :tags => ["search", "mori"],
89
108
  :title => "Why search engine find?")
90
109
  end
@@ -95,8 +114,15 @@ EOS
95
114
 
96
115
  load --table Posts
97
116
  [
98
- ["_id","author","created_at","n_goods","published","rank","tags","title"],
99
- [1,"mori",1268034720.0,4,true,10,["search","mori"],"Why search engine find?"]
117
+ ["_id","author","created_at","n_goods","published","rank","tag_text","tags","title"],
118
+ [1,"mori",1268034720.0,4,true,10,"search mori",["search","mori"],"Why search engine find?"]
119
+ ]
120
+
121
+ load --table Tags
122
+ [
123
+ ["_key","name"],
124
+ ["search",""],
125
+ ["mori",""]
100
126
  ]
101
127
 
102
128
  load --table Users
@@ -113,8 +139,8 @@ EOS
113
139
 
114
140
  load --table Posts
115
141
  [
116
- ["_id","author","created_at","n_goods","published","rank","tags","title"],
117
- [1,"mori",1268034720.0,4,true,10,["search","mori"],"Why search engine find?"]
142
+ ["_id","author","created_at","n_goods","published","rank","tag_text","tags","title"],
143
+ [1,"mori",1268034720.0,4,true,10,"search mori",["search","mori"],"Why search engine find?"]
118
144
  ]
119
145
  EOS
120
146
  end
@@ -125,8 +151,8 @@ EOS
125
151
 
126
152
  load --table Posts
127
153
  [
128
- ["_id","author","created_at","n_goods","published","rank","tags","title"],
129
- [1,"mori",1268034720.0,4,true,10,["search","mori"],"Why search engine find?"]
154
+ ["_id","author","created_at","n_goods","published","rank","tag_text","tags","title"],
155
+ [1,"mori",1268034720.0,4,true,10,"search mori",["search","mori"],"Why search engine find?"]
130
156
  ]
131
157
  EOS
132
158
  end
@@ -135,8 +161,15 @@ EOS
135
161
  assert_equal(<<-EOS, dump(:dump_schema => false))
136
162
  load --table Posts
137
163
  [
138
- ["_id","author","created_at","n_goods","published","rank","tags","title"],
139
- [1,"mori",1268034720.0,4,true,10,["search","mori"],"Why search engine find?"]
164
+ ["_id","author","created_at","n_goods","published","rank","tag_text","tags","title"],
165
+ [1,"mori",1268034720.0,4,true,10,"search mori",["search","mori"],"Why search engine find?"]
166
+ ]
167
+
168
+ load --table Tags
169
+ [
170
+ ["_key","name"],
171
+ ["search",""],
172
+ ["mori",""]
140
173
  ]
141
174
 
142
175
  load --table Users
@@ -153,4 +186,14 @@ EOS
153
186
  EOS
154
187
  end
155
188
  end
189
+
190
+ class PluginTest < DatabaseDumperTest
191
+ def test_standard_plugin
192
+ Groonga::Plugin.register("suggest/suggest")
193
+ assert_equal("register suggest/suggest\n" +
194
+ "\n" +
195
+ dumped_schema,
196
+ dump)
197
+ end
198
+ end
156
199
  end
@@ -253,8 +253,8 @@ class HashTest < Test::Unit::TestCase
253
253
  key = "niku"
254
254
  niku = users.add(key)
255
255
  assert_equal({
256
- "id" => niku.id,
257
- "key" => key,
256
+ "_id" => niku.id,
257
+ "_key" => key,
258
258
  "self_introduction" => nil,
259
259
  "age" => 0,
260
260
  },
@@ -264,8 +264,8 @@ class HashTest < Test::Unit::TestCase
264
264
  "age" => 29
265
265
  }
266
266
  assert_equal({
267
- "id" => niku.id,
268
- "key" => key,
267
+ "_id" => niku.id,
268
+ "_key" => key,
269
269
  "self_introduction" => "I'm a meet lover.",
270
270
  "age" => 29,
271
271
  },
@@ -285,8 +285,8 @@ class HashTest < Test::Unit::TestCase
285
285
  }
286
286
 
287
287
  assert_equal({
288
- "id" => users[key].id,
289
- "key" => key,
288
+ "_id" => users[key].id,
289
+ "_key" => key,
290
290
  "self_introduction" => "I'm a meet lover.",
291
291
  "age" => 29,
292
292
  },
@@ -0,0 +1,93 @@
1
+ class IndexCursorTest < Test::Unit::TestCase
2
+ include GroongaTestUtils
3
+
4
+ def setup
5
+ setup_database
6
+ setup_schema
7
+ setup_records
8
+ end
9
+
10
+ def test_open_cursor
11
+ postings = []
12
+ @terms.open_cursor do |table_cursor|
13
+ index_cursor = nil
14
+ @content_index.open_cursor(table_cursor) do |cursor|
15
+ cursor.each do |posting|
16
+ postings << posting.to_hash
17
+ end
18
+ index_cursor = cursor
19
+ end
20
+ assert_predicate(index_cursor, :closed?)
21
+ end
22
+
23
+ assert_equal(expected_postings, postings)
24
+ end
25
+
26
+ def test_enumerable
27
+ postings = nil
28
+ @terms.open_cursor do |table_cursor|
29
+ @content_index.open_cursor(table_cursor) do |cursor|
30
+ postings = cursor.collect do |posting|
31
+ posting.to_hash
32
+ end
33
+ end
34
+ end
35
+
36
+ assert_equal(expected_postings, postings)
37
+ end
38
+
39
+ private
40
+ def create_hashes(keys, values)
41
+ hashes = []
42
+ values.each do |value|
43
+ hash = {}
44
+ keys.each_with_index do |key, i|
45
+ hash[key] = value[i]
46
+ end
47
+ hashes << hash
48
+ end
49
+ hashes
50
+ end
51
+
52
+ def setup_schema
53
+ Groonga::Schema.define do |schema|
54
+ schema.create_table("Articles") do |table|
55
+ table.text("content")
56
+ end
57
+
58
+ schema.create_table("Terms",
59
+ :type => :hash,
60
+ :default_tokenizer => :bigram_split_symbol_alpha) do |table|
61
+ table.index("Articles.content")
62
+ end
63
+ end
64
+
65
+ @articles = Groonga["Articles"]
66
+ @terms = Groonga["Terms"]
67
+ @content_index = Groonga["Terms.Articles_content"]
68
+ end
69
+
70
+ def setup_records
71
+ @articles.add(:content => "l")
72
+ @articles.add(:content => "ll")
73
+ @articles.add(:content => "hello")
74
+ end
75
+
76
+ def expected_postings
77
+ parameters = [:record_id, :section_id, :term_id, :position,
78
+ :term_frequency, :weight, :n_rest_postings]
79
+
80
+ expected = [
81
+ [1, 1, 1, 0, 1, 0, 1],
82
+ [2, 1, 1, 0, 1, 0, 1],
83
+ [2, 1, 2, 0, 1, 0, 1],
84
+ [3, 1, 2, 0, 1, 0, 1],
85
+ [3, 1, 3, 0, 1, 0, 0],
86
+ [3, 1, 4, 1, 1, 0, 0],
87
+ [3, 1, 5, 3, 1, 0, 0],
88
+ [3, 1, 6, 4, 1, 0, 0]
89
+ ]
90
+
91
+ create_hashes(parameters, expected)
92
+ end
93
+ end
@@ -26,4 +26,10 @@ class PluginTest < Test::Unit::TestCase
26
26
  context.register_plugin("suggest/suggest")
27
27
  assert_not_nil(context["suggest"])
28
28
  end
29
+
30
+ def test_system_plugins_dir
31
+ suggest_plugin_path = "#{Groonga::Plugin.system_plugins_dir}/"
32
+ suggest_plugin_path << "suggest/suggest#{Groonga::Plugin.suffix}"
33
+ assert_send([File, :exist?, suggest_plugin_path])
34
+ end
29
35
  end
@@ -300,12 +300,156 @@ class RecordTest < Test::Unit::TestCase
300
300
  "comment" => "Grate!"
301
301
  }
302
302
  groonga = @bookmarks.add(values)
303
- assert_equal(values.merge("id" => groonga.id,
303
+ assert_equal(values.merge("_id" => groonga.id,
304
304
  "content" => nil,
305
305
  "user" => nil),
306
306
  groonga.attributes)
307
307
  end
308
308
 
309
+ def test_recursive_attributes
310
+ @bookmarks.define_column("next", @bookmarks)
311
+
312
+ top_page_record = @bookmarks.add(top_page)
313
+ doc_page_record = @bookmarks.add(doc_page)
314
+
315
+ top_page_record["next"] = doc_page_record
316
+ doc_page_record["next"] = top_page_record
317
+
318
+ expected = {
319
+ "_id" => 1,
320
+ "user" => nil,
321
+ "uri" => "http://groonga.org/",
322
+ "rate" => 5,
323
+ "next" => {
324
+ "_id" => 2,
325
+ "user" => nil,
326
+ "uri" => "http://groonga.org/document.html",
327
+ "rate" => 8,
328
+ "next" => {
329
+ "_table" => "Bookmarks",
330
+ "_id" => 1,
331
+ },
332
+ "content" => nil,
333
+ "comment" => "Informative"
334
+ },
335
+ "content" => nil,
336
+ "comment" => "Great!"
337
+ }
338
+
339
+ assert_equal(expected, top_page_record.attributes)
340
+ end
341
+
342
+ def test_select_result_attributes
343
+ top_page_record = @bookmarks.add(top_page)
344
+ select_result = @bookmarks.select
345
+ select_result_result = select_result.first
346
+
347
+ expected_attributes = {
348
+ "_id" => 1,
349
+ "_key" => {
350
+ "comment" => "Great!",
351
+ "content" => nil,
352
+ "_id" => 1,
353
+ "rate" => 5,
354
+ "uri" => "http://groonga.org/",
355
+ "user" => nil
356
+ },
357
+ "_nsubrecs" => 1,
358
+ "_score" => 1,
359
+ }
360
+
361
+ assert_equal(expected_attributes, select_result_result.attributes)
362
+ end
363
+
364
+ def test_self_referencing_attributes
365
+ @bookmarks.define_column("next", @bookmarks)
366
+
367
+ top_page_record = @bookmarks.add(top_page)
368
+ top_page_record["next"] = top_page_record
369
+
370
+ expected = {
371
+ "_id" => 1,
372
+ "user" => nil,
373
+ "uri" => "http://groonga.org/",
374
+ "rate" => 5,
375
+ "next" => {
376
+ "_table" => "Bookmarks",
377
+ "_id" => 1
378
+ },
379
+ "content" => nil,
380
+ "comment" => "Great!"
381
+ }
382
+
383
+ assert_equal(expected, top_page_record.attributes)
384
+ end
385
+
386
+ def test_vector_attributes
387
+ @bookmarks.define_column("related_bookmarks", @bookmarks, :type => :vector)
388
+
389
+ top_page_record = @bookmarks.add(top_page)
390
+ doc_page_record = @bookmarks.add(doc_page)
391
+ top_page_record["related_bookmarks"] = [doc_page_record]
392
+
393
+ expected = {
394
+ "_id" => 1,
395
+ "user" => nil,
396
+ "uri" => "http://groonga.org/",
397
+ "rate" => 5,
398
+ "related_bookmarks" => [
399
+ {
400
+ "_id" => 2,
401
+ "comment" => "Informative",
402
+ "content" => nil,
403
+ "rate" => 8,
404
+ "related_bookmarks" => [],
405
+ "uri" => "http://groonga.org/document.html",
406
+ "user" => nil,
407
+ }
408
+ ],
409
+ "content" => nil,
410
+ "comment" => "Great!"
411
+ }
412
+
413
+ assert_equal(expected, top_page_record.attributes)
414
+ end
415
+
416
+ def test_self_referencing_vector_attributes
417
+ @bookmarks.define_column("related_bookmarks", @bookmarks, :type => :vector)
418
+
419
+ top_page_record = @bookmarks.add(top_page)
420
+ doc_page_record = @bookmarks.add(doc_page)
421
+ top_page_record["related_bookmarks"] = [
422
+ top_page_record,
423
+ doc_page_record
424
+ ]
425
+
426
+ expected = {
427
+ "_id" => 1,
428
+ "user" => nil,
429
+ "uri" => "http://groonga.org/",
430
+ "rate" => 5,
431
+ "related_bookmarks" => [
432
+ {
433
+ "_table" => "Bookmarks",
434
+ "_id" => 1
435
+ },
436
+ {
437
+ "_id" => 2,
438
+ "comment" => "Informative",
439
+ "content" => nil,
440
+ "rate" => 8,
441
+ "related_bookmarks" => [],
442
+ "uri" => "http://groonga.org/document.html",
443
+ "user" => nil,
444
+ }
445
+ ],
446
+ "content" => nil,
447
+ "comment" => "Great!"
448
+ }
449
+
450
+ assert_equal(expected, top_page_record.attributes)
451
+ end
452
+
309
453
  def test_dynamic_accessor
310
454
  groonga = @bookmarks.add
311
455
  assert_equal([],
@@ -358,4 +502,21 @@ class RecordTest < Test::Unit::TestCase
358
502
  kou = @users.add("kou")
359
503
  kou.addresses = array_like_object
360
504
  end
505
+
506
+ private
507
+ def top_page
508
+ {
509
+ "uri" => "http://groonga.org/",
510
+ "rate" => 5,
511
+ "comment" => "Great!",
512
+ }
513
+ end
514
+
515
+ def doc_page
516
+ {
517
+ "uri" => "http://groonga.org/document.html",
518
+ "rate" => 8,
519
+ "comment" => "Informative"
520
+ }
521
+ end
361
522
  end