xapit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. data/LICENSE +20 -0
  2. data/Manifest +178 -0
  3. data/README.rdoc +183 -0
  4. data/Rakefile +15 -0
  5. data/TODO +23 -0
  6. data/features/facets.feature +51 -0
  7. data/features/finding.feature +119 -0
  8. data/features/indexing.feature +41 -0
  9. data/features/step_definitions/common_steps.rb +7 -0
  10. data/features/step_definitions/xapit_steps.rb +117 -0
  11. data/features/support/env.rb +7 -0
  12. data/features/support/xapit_helpers.rb +27 -0
  13. data/init.rb +3 -0
  14. data/install.rb +9 -0
  15. data/lib/xapit.rb +39 -0
  16. data/lib/xapit/collection.rb +165 -0
  17. data/lib/xapit/config.rb +83 -0
  18. data/lib/xapit/facet.rb +59 -0
  19. data/lib/xapit/facet_blueprint.rb +59 -0
  20. data/lib/xapit/facet_option.rb +56 -0
  21. data/lib/xapit/index_blueprint.rb +117 -0
  22. data/lib/xapit/indexers/abstract_indexer.rb +101 -0
  23. data/lib/xapit/indexers/classic_indexer.rb +27 -0
  24. data/lib/xapit/indexers/simple_indexer.rb +31 -0
  25. data/lib/xapit/membership.rb +103 -0
  26. data/lib/xapit/query.rb +62 -0
  27. data/lib/xapit/query_parsers/abstract_query_parser.rb +115 -0
  28. data/lib/xapit/query_parsers/classic_query_parser.rb +19 -0
  29. data/lib/xapit/query_parsers/simple_query_parser.rb +75 -0
  30. data/spec/spec_helper.rb +15 -0
  31. data/spec/tmp/xapdb/flintlock +0 -0
  32. data/spec/tmp/xapdb/iamflint +0 -0
  33. data/spec/tmp/xapdb/postlist.DB +0 -0
  34. data/spec/tmp/xapdb/postlist.baseA +0 -0
  35. data/spec/tmp/xapdb/postlist.baseB +0 -0
  36. data/spec/tmp/xapdb/record.DB +0 -0
  37. data/spec/tmp/xapdb/record.baseA +0 -0
  38. data/spec/tmp/xapdb/record.baseB +0 -0
  39. data/spec/tmp/xapdb/spelling.DB +0 -0
  40. data/spec/tmp/xapdb/spelling.baseA +0 -0
  41. data/spec/tmp/xapdb/spelling.baseB +0 -0
  42. data/spec/tmp/xapdb/termlist.DB +0 -0
  43. data/spec/tmp/xapdb/termlist.baseA +0 -0
  44. data/spec/tmp/xapdb/termlist.baseB +0 -0
  45. data/spec/tmp/xapian_db/flintlock +0 -0
  46. data/spec/tmp/xapian_db/iamflint +0 -0
  47. data/spec/tmp/xapian_db/postlist.DB +0 -0
  48. data/spec/tmp/xapian_db/postlist.baseA +0 -0
  49. data/spec/tmp/xapian_db/record.DB +0 -0
  50. data/spec/tmp/xapian_db/record.baseA +0 -0
  51. data/spec/tmp/xapian_db/termlist.DB +0 -0
  52. data/spec/tmp/xapian_db/termlist.baseA +0 -0
  53. data/spec/tmp/xapiandab/flintlock +0 -0
  54. data/spec/tmp/xapiandab/iamflint +0 -0
  55. data/spec/tmp/xapiandab/postlist.DB +0 -0
  56. data/spec/tmp/xapiandab/postlist.baseA +0 -0
  57. data/spec/tmp/xapiandab/postlist.baseB +0 -0
  58. data/spec/tmp/xapiandab/record.DB +0 -0
  59. data/spec/tmp/xapiandab/record.baseA +0 -0
  60. data/spec/tmp/xapiandab/record.baseB +0 -0
  61. data/spec/tmp/xapiandab/spelling.DB +0 -0
  62. data/spec/tmp/xapiandab/spelling.baseA +0 -0
  63. data/spec/tmp/xapiandab/spelling.baseB +0 -0
  64. data/spec/tmp/xapiandab/termlist.DB +0 -0
  65. data/spec/tmp/xapiandab/termlist.baseA +0 -0
  66. data/spec/tmp/xapiandab/termlist.baseB +0 -0
  67. data/spec/tmp/xapiandatab/flintlock +0 -0
  68. data/spec/tmp/xapiandatab/iamflint +0 -0
  69. data/spec/tmp/xapiandatab/postlist.DB +0 -0
  70. data/spec/tmp/xapiandatab/postlist.baseA +0 -0
  71. data/spec/tmp/xapiandatab/postlist.baseB +0 -0
  72. data/spec/tmp/xapiandatab/record.DB +0 -0
  73. data/spec/tmp/xapiandatab/record.baseA +0 -0
  74. data/spec/tmp/xapiandatab/record.baseB +0 -0
  75. data/spec/tmp/xapiandatab/spelling.DB +0 -0
  76. data/spec/tmp/xapiandatab/spelling.baseA +0 -0
  77. data/spec/tmp/xapiandatab/spelling.baseB +0 -0
  78. data/spec/tmp/xapiandatab/termlist.DB +0 -0
  79. data/spec/tmp/xapiandatab/termlist.baseA +0 -0
  80. data/spec/tmp/xapiandatab/termlist.baseB +0 -0
  81. data/spec/tmp/xapiandataba/flintlock +0 -0
  82. data/spec/tmp/xapiandataba/iamflint +0 -0
  83. data/spec/tmp/xapiandataba/postlist.DB +0 -0
  84. data/spec/tmp/xapiandataba/postlist.baseA +0 -0
  85. data/spec/tmp/xapiandataba/postlist.baseB +0 -0
  86. data/spec/tmp/xapiandataba/record.DB +0 -0
  87. data/spec/tmp/xapiandataba/record.baseA +0 -0
  88. data/spec/tmp/xapiandataba/record.baseB +0 -0
  89. data/spec/tmp/xapiandataba/spelling.DB +0 -0
  90. data/spec/tmp/xapiandataba/spelling.baseA +0 -0
  91. data/spec/tmp/xapiandataba/spelling.baseB +0 -0
  92. data/spec/tmp/xapiandataba/termlist.DB +0 -0
  93. data/spec/tmp/xapiandataba/termlist.baseA +0 -0
  94. data/spec/tmp/xapiandataba/termlist.baseB +0 -0
  95. data/spec/tmp/xapiandatabas/flintlock +0 -0
  96. data/spec/tmp/xapiandatabas/iamflint +0 -0
  97. data/spec/tmp/xapiandatabas/postlist.DB +0 -0
  98. data/spec/tmp/xapiandatabas/postlist.baseA +0 -0
  99. data/spec/tmp/xapiandatabas/record.DB +0 -0
  100. data/spec/tmp/xapiandatabas/record.baseA +0 -0
  101. data/spec/tmp/xapiandatabas/termlist.DB +0 -0
  102. data/spec/tmp/xapiandatabas/termlist.baseA +0 -0
  103. data/spec/tmp/xapiandatb/flintlock +0 -0
  104. data/spec/tmp/xapiandatb/iamflint +0 -0
  105. data/spec/tmp/xapiandatb/postlist.DB +0 -0
  106. data/spec/tmp/xapiandatb/postlist.baseA +0 -0
  107. data/spec/tmp/xapiandatb/postlist.baseB +0 -0
  108. data/spec/tmp/xapiandatb/record.DB +0 -0
  109. data/spec/tmp/xapiandatb/record.baseA +0 -0
  110. data/spec/tmp/xapiandatb/record.baseB +0 -0
  111. data/spec/tmp/xapiandatb/spelling.DB +0 -0
  112. data/spec/tmp/xapiandatb/spelling.baseA +0 -0
  113. data/spec/tmp/xapiandatb/spelling.baseB +0 -0
  114. data/spec/tmp/xapiandatb/termlist.DB +0 -0
  115. data/spec/tmp/xapiandatb/termlist.baseA +0 -0
  116. data/spec/tmp/xapiandatb/termlist.baseB +0 -0
  117. data/spec/tmp/xapiandbase/flintlock +0 -0
  118. data/spec/tmp/xapiandbase/iamflint +0 -0
  119. data/spec/tmp/xapiandbase/postlist.DB +0 -0
  120. data/spec/tmp/xapiandbase/postlist.baseA +0 -0
  121. data/spec/tmp/xapiandbase/postlist.baseB +0 -0
  122. data/spec/tmp/xapiandbase/record.DB +0 -0
  123. data/spec/tmp/xapiandbase/record.baseA +0 -0
  124. data/spec/tmp/xapiandbase/record.baseB +0 -0
  125. data/spec/tmp/xapiandbase/spelling.DB +0 -0
  126. data/spec/tmp/xapiandbase/spelling.baseA +0 -0
  127. data/spec/tmp/xapiandbase/spelling.baseB +0 -0
  128. data/spec/tmp/xapiandbase/termlist.DB +0 -0
  129. data/spec/tmp/xapiandbase/termlist.baseA +0 -0
  130. data/spec/tmp/xapiandbase/termlist.baseB +0 -0
  131. data/spec/xapit/collection_spec.rb +153 -0
  132. data/spec/xapit/config_spec.rb +48 -0
  133. data/spec/xapit/facet_blueprint_spec.rb +29 -0
  134. data/spec/xapit/facet_option_spec.rb +80 -0
  135. data/spec/xapit/facet_spec.rb +73 -0
  136. data/spec/xapit/index_blueprint_spec.rb +60 -0
  137. data/spec/xapit/indexers/abstract_indexer_spec.rb +74 -0
  138. data/spec/xapit/indexers/classic_indexer_spec.rb +26 -0
  139. data/spec/xapit/indexers/simple_indexer_spec.rb +53 -0
  140. data/spec/xapit/membership_spec.rb +39 -0
  141. data/spec/xapit/query_parsers/abstract_query_parser_spec.rb +23 -0
  142. data/spec/xapit/query_parsers/classic_query_parser_spec.rb +15 -0
  143. data/spec/xapit/query_parsers/simple_query_parser_spec.rb +86 -0
  144. data/spec/xapit/query_spec.rb +41 -0
  145. data/spec/xapit_member.rb +32 -0
  146. data/tasks/spec.rb +9 -0
  147. data/tasks/xapit.rake +9 -0
  148. data/tmp/xapiandatabase/flintlock +0 -0
  149. data/tmp/xapiandatabase/iamflint +0 -0
  150. data/tmp/xapiandatabase/postlist.DB +0 -0
  151. data/tmp/xapiandatabase/postlist.baseA +0 -0
  152. data/tmp/xapiandatabase/postlist.baseB +0 -0
  153. data/tmp/xapiandatabase/record.DB +0 -0
  154. data/tmp/xapiandatabase/record.baseA +0 -0
  155. data/tmp/xapiandatabase/record.baseB +0 -0
  156. data/tmp/xapiandatabase/spelling.DB +0 -0
  157. data/tmp/xapiandatabase/spelling.baseA +0 -0
  158. data/tmp/xapiandatabase/spelling.baseB +0 -0
  159. data/tmp/xapiandatabase/termlist.DB +0 -0
  160. data/tmp/xapiandatabase/termlist.baseA +0 -0
  161. data/tmp/xapiandatabase/termlist.baseB +0 -0
  162. data/tmp/xapiandatabase/value.baseB +0 -0
  163. data/tmp/xapiandb/flintlock +0 -0
  164. data/tmp/xapiandb/iamflint +0 -0
  165. data/tmp/xapiandb/postlist.DB +0 -0
  166. data/tmp/xapiandb/postlist.baseA +0 -0
  167. data/tmp/xapiandb/postlist.baseB +0 -0
  168. data/tmp/xapiandb/record.DB +0 -0
  169. data/tmp/xapiandb/record.baseA +0 -0
  170. data/tmp/xapiandb/record.baseB +0 -0
  171. data/tmp/xapiandb/spelling.DB +0 -0
  172. data/tmp/xapiandb/spelling.baseA +0 -0
  173. data/tmp/xapiandb/spelling.baseB +0 -0
  174. data/tmp/xapiandb/termlist.DB +0 -0
  175. data/tmp/xapiandb/termlist.baseA +0 -0
  176. data/tmp/xapiandb/termlist.baseB +0 -0
  177. data/tmp/xapiandb/value.baseB +0 -0
  178. data/uninstall.rb +5 -0
  179. data/xapit.gemspec +30 -0
  180. metadata +257 -0
File without changes
Binary file
Binary file
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,153 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Xapit::Collection do
4
+ describe "with database" do
5
+ before(:each) do
6
+ XapitMember.xapit do |index|
7
+ index.text :name
8
+ index.field :name
9
+ index.facet :name
10
+ index.sortable :name
11
+ end
12
+ end
13
+
14
+ describe "indexed" do
15
+ before(:each) do
16
+ @hello = XapitMember.new(:name => "hello world")
17
+ @foo = XapitMember.new(:name => "foo bar")
18
+ Xapit.index_all
19
+ end
20
+
21
+ it "should find all xapit members in database given nil" do
22
+ Xapit::Collection.new(XapitMember, nil).should == [@hello, @foo]
23
+ end
24
+
25
+ it "should matching xapit member given a word" do
26
+ Xapit::Collection.new(XapitMember, "foo").should == [@foo]
27
+ end
28
+
29
+ it "should not be case sensitive on query matching" do
30
+ Xapit::Collection.new(XapitMember, "BAR Foo").should == [@foo]
31
+ end
32
+
33
+ it "should have 2 records for empty string" do
34
+ Xapit::Collection.new(XapitMember, "").size.should == 2
35
+ end
36
+
37
+ it "should not be empty for blank query" do
38
+ Xapit::Collection.new(XapitMember, "").empty?.should be_false
39
+ end
40
+
41
+ it "should filter by conditions, case insensitive" do
42
+ Xapit::Collection.new(XapitMember, "", :conditions => { :name => "HELLO world"}).should == [@hello]
43
+ end
44
+
45
+ it "should know first entry" do
46
+ Xapit::Collection.new(XapitMember, "").first.should == @hello
47
+ end
48
+
49
+ it "should know last entry" do
50
+ Xapit::Collection.new(XapitMember, "").last.should == @foo
51
+ end
52
+
53
+ it "should support nested search" do
54
+ Xapit::Collection.new(XapitMember, "world").search("foo") == [@foo]
55
+ end
56
+
57
+ it "should support page and per_page options" do
58
+ Xapit::Collection.new(XapitMember, :page => 1, :per_page => 1).should == [@hello]
59
+ Xapit::Collection.new(XapitMember, :page => 2, :per_page => 1).should == [@foo]
60
+ end
61
+
62
+ it "should have offset" do
63
+ Xapit::Collection.new(XapitMember, :page => 2, :per_page => 1).offset.should == 1
64
+ end
65
+
66
+ it "should have total_entries, total_pages, current_page, per_page, previous_page, next_page" do
67
+ collection = Xapit::Collection.new(XapitMember, "", :per_page => 1, :page => 2)
68
+ collection.total_entries.should == 2
69
+ collection.total_pages.should == 2
70
+ collection.previous_page.should == 1
71
+ collection.next_page.should be_nil
72
+ end
73
+
74
+ it "should set xapit_relevance in results" do
75
+ results = Xapit::Collection.new(XapitMember, "")
76
+ results.each do |record|
77
+ record.xapit_relevance.class.should == Fixnum
78
+ end
79
+ end
80
+
81
+ it "should find nothing when searching unknown facet" do
82
+ Xapit::Collection.new(XapitMember, :facets => ["unknownfacet"]).should be_empty
83
+ end
84
+
85
+ it "should find matching facet" do
86
+ ids = Xapit::FacetBlueprint.new(XapitMember, 0, :name).identifiers_for(@hello)
87
+ Xapit::Collection.new(XapitMember, :facets => ids*2).should == [@hello]
88
+ end
89
+
90
+ it "should split facets string on dash" do
91
+ ids = Xapit::FacetBlueprint.new(XapitMember, 0, :name).identifiers_for(@hello)
92
+ Xapit::Collection.new(XapitMember, :facets => (ids*2).join("-")).should == [@hello]
93
+ end
94
+
95
+ it "should have one facet with two options with blank keywords" do
96
+ facets = Xapit::Collection.new(XapitMember, "").facets
97
+ facets.size.should == 1
98
+ facets.first.options.size.should == 2
99
+ end
100
+
101
+ it "should have no applied facets when there are no given facets" do
102
+ Xapit::Collection.new(XapitMember, "").applied_facet_options.should be_empty
103
+ end
104
+
105
+ it "should list applied facets" do
106
+ ids = Xapit::FacetBlueprint.new(XapitMember, 0, :name).identifiers_for(@hello)
107
+ results = Xapit::Collection.new(XapitMember, "", :facets => (ids*2).join("-"))
108
+ results.applied_facet_options.map(&:name).should == ["hello world", "hello world"]
109
+ end
110
+
111
+ it "should pass existing facet identifiers to applied options" do
112
+ ids = Xapit::FacetBlueprint.new(XapitMember, 0, :name).identifiers_for(@hello)
113
+ results = Xapit::Collection.new(XapitMember, "", :facets => (ids*2).join("-"))
114
+ results.applied_facet_options.first.existing_facet_identifiers.should == (ids*2)
115
+ end
116
+
117
+ it "should sort records in specified order" do
118
+ Xapit::Collection.new(XapitMember, :order => :name).should == [@foo, @hello]
119
+ end
120
+
121
+ it "should have no spelling suggestions for empty query" do
122
+ Xapit::Collection.new(XapitMember).spelling_suggestion.should == nil
123
+ end
124
+
125
+ it "should have no spelling suggestion for very different query" do
126
+ Xapit::Collection.new(XapitMember, "match nothing").spelling_suggestion.should == nil
127
+ end
128
+
129
+ it "should have spelling suggestion for single-word query" do
130
+ Xapit::Collection.new(XapitMember, "wrld").spelling_suggestion.should == "world"
131
+ end
132
+
133
+ it "should have spelling suggestion for multi-word query" do
134
+ Xapit::Collection.new(XapitMember, "helo bat wrld").spelling_suggestion.should == "hello bar world"
135
+ end
136
+
137
+ it "should raise error when fetching spelling suggestion if spelling is disabled" do
138
+ Xapit::Config.options[:spelling] = false
139
+ lambda { Xapit::Collection.new(XapitMember, "foo").spelling_suggestion }.should raise_error
140
+ end
141
+
142
+ it "should find similar records" do
143
+ member = XapitMember.new(:name => "foo bar world")
144
+ Xapit::Collection.search_similar(member).should == [@foo, @hello]
145
+ end
146
+
147
+ it "should be able to specify classes" do
148
+ Xapit::Collection.new(nil, "foo", :classes => [String, Array]).should == []
149
+ Xapit::Collection.new(nil, "foo", :classes => [String, Array, XapitMember]).should == [@foo]
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Xapit::Config do
4
+ it "should be able to set database path and fetch writable or readable" do
5
+ Xapit::Config.writable_database.should be_kind_of(Xapian::WritableDatabase)
6
+ Xapit::Config.database.should be_kind_of(Xapian::Database)
7
+ end
8
+
9
+ it "should default query parser to SimpleQueryParser" do
10
+ Xapit::Config.setup
11
+ Xapit::Config.query_parser.should == Xapit::ClassicQueryParser
12
+ end
13
+
14
+ it "should be able to set query parser on setup" do
15
+ Xapit::Config.setup(:query_parser => Xapit::SimpleQueryParser)
16
+ Xapit::Config.query_parser.should == Xapit::SimpleQueryParser
17
+ end
18
+
19
+ it "should default indexer to SimpleIndexer" do
20
+ Xapit::Config.setup
21
+ Xapit::Config.indexer.should == Xapit::SimpleIndexer
22
+ end
23
+
24
+ it "should be able to set indexer on setup" do
25
+ Xapit::Config.setup(:indexer => Xapit::ClassicIndexer)
26
+ Xapit::Config.indexer.should == Xapit::ClassicIndexer
27
+ end
28
+
29
+ it "should have spelling enabled by default" do
30
+ Xapit::Config.setup
31
+ Xapit::Config.spelling?.should be_true
32
+ end
33
+
34
+ it "should be able to specify spelling setting at setup" do
35
+ Xapit::Config.setup(:spelling => false)
36
+ Xapit::Config.spelling?.should be_false
37
+ end
38
+
39
+ it "should default stemming to english" do
40
+ Xapit::Config.setup
41
+ Xapit::Config.stemming == "english"
42
+ end
43
+
44
+ it "should be able to specify stemming setting at setup" do
45
+ Xapit::Config.setup(:stemming => "german")
46
+ Xapit::Config.stemming == "german"
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Xapit::FacetBlueprint do
4
+ it "should generate unique identifier based on attribute and value" do
5
+ facet1 = Xapit::FacetBlueprint.new(XapitMember, 0, :to_s)
6
+ facet2 = Xapit::FacetBlueprint.new(XapitMember, 0, :length)
7
+ facet1.identifiers_for("foo").first.length.should == 7
8
+ facet1.identifiers_for("foo").should_not == facet1.identifiers_for("bar")
9
+ facet1.identifiers_for("foo").should_not == facet2.identifiers_for("foo")
10
+ end
11
+
12
+ it "should generate unique identifiers for each value returned" do
13
+ facet = Xapit::FacetBlueprint.new(XapitMember, 0, :to_a)
14
+ facet.identifiers_for(["foo", "bar"]).size.should == 2
15
+ end
16
+
17
+ it "should humanize attribute for name if one isn't given" do
18
+ Xapit::FacetBlueprint.new(XapitMember, 0, :visible).name.should == "Visible"
19
+ end
20
+
21
+ it "should use custom name if given" do
22
+ Xapit::FacetBlueprint.new(XapitMember, 0, :visible, "custom").name.should == "custom"
23
+ end
24
+
25
+ it "should not have identifiers for blank values" do
26
+ facet = Xapit::FacetBlueprint.new(XapitMember, 0, :to_a)
27
+ facet.identifiers_for(["", nil, "bar"]).size.should == 1
28
+ end
29
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Xapit::FacetOption do
4
+ it "should combine previous identifiers with current one on to_param" do
5
+ option = Xapit::FacetOption.new(nil, nil, nil)
6
+ option.existing_facet_identifiers = ["abc", "123"]
7
+ stub(option).identifier { "foo" }
8
+ option.to_param.should == "abc-123-foo"
9
+ end
10
+
11
+ it "should remove current identifier from previous identifiers if it exists" do
12
+ Xapit::Config.setup(:breadcrumb_facets => false)
13
+ option = Xapit::FacetOption.new(nil, nil, nil)
14
+ option.existing_facet_identifiers = ["abc", "123", "foo"]
15
+ stub(option).identifier { "foo" }
16
+ option.to_param.should == "abc-123"
17
+ end
18
+
19
+ it "should support breadcrumb style facets" do
20
+ Xapit::Config.setup(:breadcrumb_facets => true)
21
+ option = Xapit::FacetOption.new(nil, nil, nil)
22
+ option.existing_facet_identifiers = ["abc", "123", "foo"]
23
+ stub(option).identifier { "123" }
24
+ option.to_param.should == "abc-123"
25
+ end
26
+
27
+ describe "with database" do
28
+ before(:each) do
29
+ XapitMember.xapit do |index|
30
+ index.facet :age, "Person Age"
31
+ index.facet :category
32
+ end
33
+ end
34
+
35
+ it "should have identifier hashing name and value" do
36
+ option = Xapit::FacetOption.new("XapitMember", "age", "17")
37
+ option.identifier.should == "0c93ee1"
38
+ end
39
+
40
+ it "should find facet option from database given id" do
41
+ doc = Xapian::Document.new
42
+ doc.data = "XapitMember|||age|||17"
43
+ doc.add_term("QXapit::FacetOption-abc123")
44
+ Xapit::Config.writable_database.add_document(doc)
45
+ option = Xapit::FacetOption.find("abc123")
46
+ option.name.should == "17"
47
+ option.facet.name.should == "Person Age"
48
+ end
49
+
50
+ it "should save facet to database" do
51
+ Xapit::Config.writable_database # make sure there's a database setup in case we try to read from it
52
+ option = Xapit::FacetOption.new(nil, nil, nil)
53
+ option.facet = XapitMember.xapit_facet_blueprint("age")
54
+ option.name = "23"
55
+ option.save
56
+ Xapit::FacetOption.find(option.identifier).should_not be_nil
57
+ end
58
+
59
+ it "should not save facet if it already exists" do
60
+ doc = Xapian::Document.new
61
+ doc.data = "XapitMember|||age|||17"
62
+ doc.add_term("QXapit::FacetOption-abc123")
63
+ Xapit::Config.writable_database.add_document(doc)
64
+ stub(Xapit::Config.writable_database).add_document { raise "should not add doc" }
65
+ option = Xapit::FacetOption.new(XapitMember, nil, nil)
66
+ stub(option).identifier { "abc123" }
67
+ option.save
68
+ end
69
+
70
+ it "should find facet option which doesn't have a value" do
71
+ doc = Xapian::Document.new
72
+ doc.data = "XapitMember|||age|||"
73
+ doc.add_term("QXapit::FacetOption-abc123")
74
+ Xapit::Config.writable_database.add_document(doc)
75
+ option = Xapit::FacetOption.find("abc123")
76
+ option.name.should == ""
77
+ option.facet.name.should == "Person Age"
78
+ end
79
+ end
80
+ end