aqua 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/Aqua.gemspec +14 -11
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/aqua.rb +5 -7
- data/lib/aqua/object/config.rb +2 -3
- data/lib/aqua/object/initializers.rb +309 -0
- data/lib/aqua/object/pack.rb +56 -132
- data/lib/aqua/object/query.rb +30 -2
- data/lib/aqua/object/stub.rb +60 -95
- data/lib/aqua/object/tank.rb +1 -0
- data/lib/aqua/object/translator.rb +313 -0
- data/lib/aqua/object/unpack.rb +26 -227
- data/lib/aqua/store/couch_db/couch_db.rb +1 -0
- data/lib/aqua/store/couch_db/database.rb +1 -1
- data/lib/aqua/store/couch_db/design_document.rb +126 -2
- data/lib/aqua/store/couch_db/result_set.rb +36 -0
- data/lib/aqua/store/couch_db/storage_methods.rb +182 -17
- data/lib/aqua/store/storage.rb +4 -48
- data/lib/aqua/support/mash.rb +2 -3
- data/lib/aqua/support/set.rb +4 -16
- data/spec/object/object_fixtures/array_udder.rb +1 -1
- data/spec/object/object_fixtures/persistent.rb +0 -2
- data/spec/object/pack_spec.rb +137 -517
- data/spec/object/query_spec.rb +36 -6
- data/spec/object/stub_spec.rb +10 -9
- data/spec/object/translator_packing_spec.rb +402 -0
- data/spec/object/translator_unpacking_spec.rb +262 -0
- data/spec/object/unpack_spec.rb +162 -320
- data/spec/spec_helper.rb +18 -0
- data/spec/store/couchdb/design_document_spec.rb +148 -7
- data/spec/store/couchdb/result_set_spec.rb +95 -0
- data/spec/store/couchdb/storage_methods_spec.rb +150 -10
- metadata +13 -9
- data/lib/aqua/support/initializers.rb +0 -216
- data/spec/object/object_fixtures/grounded.rb +0 -13
- data/spec/object/object_fixtures/sugar.rb +0 -4
data/spec/spec_helper.rb
CHANGED
@@ -9,6 +9,24 @@ def require_fixtures
|
|
9
9
|
Dir[ File.dirname(__FILE__) + "/object/object_fixtures/**/*.rb" ].each do |file|
|
10
10
|
require file
|
11
11
|
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_user_ivars
|
15
|
+
@time = Time.now
|
16
|
+
@date = Date.parse('12/23/1969')
|
17
|
+
@message = "Hello World! This is a log entry"
|
18
|
+
@log = Log.new( :message => @message, :created_at => @time ) # embedded object
|
19
|
+
@other_user = User.new( :username => 'strictnine', :name => ['What', 'Ever'] ) # stubbed objects
|
20
|
+
@user = User.new(
|
21
|
+
:username => 'kane',
|
22
|
+
:name => ['Kane', 'Baccigalupi'],
|
23
|
+
:dob => @date,
|
24
|
+
:created_at => @time,
|
25
|
+
:log => @log,
|
26
|
+
:password => 'my secret!',
|
27
|
+
:other_user => @other_user
|
28
|
+
)
|
29
|
+
@pack = @user._pack
|
12
30
|
end
|
13
31
|
|
14
32
|
|
@@ -7,18 +7,18 @@ CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
|
7
7
|
Database = CouchDB::Database unless defined?( Database )
|
8
8
|
Server = CouchDB::Server unless defined?( Server )
|
9
9
|
Design = CouchDB::DesignDocument unless defined?( Design )
|
10
|
+
ResultSet = CouchDB::ResultSet unless defined?( ResultSet )
|
11
|
+
|
12
|
+
require File.dirname(__FILE__) + '/fixtures_and_data/document_fixture' # Document ... a Mash with the collection of methods
|
10
13
|
|
11
14
|
describe CouchDB::DesignDocument do
|
12
15
|
before(:each) do
|
13
16
|
Aqua::Storage.database.delete_all
|
17
|
+
@name = 'User'
|
18
|
+
@design = Design.new(:name => @name)
|
14
19
|
end
|
15
20
|
|
16
21
|
describe 'new and create' do
|
17
|
-
before(:each) do
|
18
|
-
@name = 'User'
|
19
|
-
@design = Design.new(:name => @name)
|
20
|
-
end
|
21
|
-
|
22
22
|
it 'should require a name to build the uri' do
|
23
23
|
design = Design.new
|
24
24
|
lambda{ design.uri }.should raise_error
|
@@ -35,9 +35,150 @@ describe CouchDB::DesignDocument do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
it 'should get a design document by name' do
|
39
|
+
@design.save!
|
40
|
+
lambda{ Design.get( @name ) }.should_not raise_error
|
41
|
+
end
|
42
|
+
|
38
43
|
describe 'views' do
|
44
|
+
before(:each) do
|
45
|
+
ResultSet.document_class = Document
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should be a Hash-like object' do
|
49
|
+
@design.views.should == Mash.new
|
50
|
+
end
|
39
51
|
|
40
|
-
|
41
|
-
|
52
|
+
describe '<<, add, add!' do
|
53
|
+
describe 'string as argument' do
|
54
|
+
it 'should add a view with the right name' do
|
55
|
+
@design << 'my_attribute'
|
56
|
+
@design.views.keys.should == ['my_attribute']
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should autogenerate a generic map' do
|
60
|
+
@design << 'my_attribute'
|
61
|
+
@design.views[:my_attribute][:map].should match(/function\(doc\)/)
|
62
|
+
@design.views[:my_attribute][:map].should match(/emit/)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should not autogenerate a reduce function' do
|
66
|
+
@design << 'my_attribute'
|
67
|
+
@design.views[:my_attribute][:reduce].should be_nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'hash options as argument' do
|
72
|
+
it 'should add a view named with the options name key' do
|
73
|
+
@design << {:name => 'my_attribute'}
|
74
|
+
@design.views.keys.should == ['my_attribute']
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should autogenerate a generic map' do
|
78
|
+
@design << {:name => 'my_attribute'}
|
79
|
+
@design.views[:my_attribute][:map].should match(/function\(doc\)/)
|
80
|
+
@design.views[:my_attribute][:map].should match(/emit/)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should autogenerate a generic map with class constraints' do
|
84
|
+
@design << {:name => 'my_docs', :class_constraint => Document}
|
85
|
+
@design.views[:my_docs][:map].should match(/doc\['type'\] == 'Document'/)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should autogenerate a generic map and insert preformed class constraints' do
|
89
|
+
@design << {:name => 'user', :class_constraint => "doc['class'] == 'User'" }
|
90
|
+
@design.views[:user][:map].should match(/doc\['class'\] == 'User'/)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should not autogenerate a reduce function' do
|
94
|
+
@design << {:name => 'my_attribute'}
|
95
|
+
@design.views[:my_attribute][:reduce].should be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should apply a map option when provided' do
|
99
|
+
@design << {:name => 'my_attribute', :map => 'not the generic'}
|
100
|
+
@design.views[:my_attribute][:map].should == 'not the generic'
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should apply a reduce option when provided' do
|
104
|
+
@design << {:name => 'my_attribute', :reduce => 'I exist!'}
|
105
|
+
@design.views[:my_attribute][:map].should match(/function\(doc\)/)
|
106
|
+
@design.views[:my_attribute][:map].should match(/emit/)
|
107
|
+
@design.views[:my_attribute][:reduce].should == 'I exist!'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'add should act like <<' do
|
112
|
+
@design.add :name => 'my_attribute', :map => 'not the generic'
|
113
|
+
@design.views[:my_attribute][:map].should == 'not the generic'
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'add! should save after adding the view' do
|
117
|
+
@design.add! :name => 'my_attribute', :map => 'not the generic'
|
118
|
+
lambda{ Design.get( @design.name ) }.should_not raise_error
|
119
|
+
design = Design.get( @design.name )
|
120
|
+
design.views.keys.should include( 'my_attribute' )
|
121
|
+
end
|
122
|
+
end
|
42
123
|
|
124
|
+
describe 'query' do
|
125
|
+
before(:each) do
|
126
|
+
(1..10).each do |num|
|
127
|
+
Document.create!( :index => num )
|
128
|
+
end
|
129
|
+
@design << :index
|
130
|
+
@design.save!
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should query by saved view' do
|
134
|
+
lambda{ @design.query( :index ) }.should_not raise_error
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should return a number of rows corresponding to all the documents in the query' do
|
138
|
+
@docs = @design.query( :index )
|
139
|
+
@docs.size.should == 10
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should return the documents themselves by default' do
|
143
|
+
@docs = @design.query( :index )
|
144
|
+
@docs.first.keys.should include( 'index' )
|
145
|
+
@docs.first.class.should == Document
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should limit query results' do
|
149
|
+
@docs = @design.query( :index, :limit => 2 )
|
150
|
+
@docs.size.should == 2
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should offset query results' do
|
154
|
+
@docs = @design.query( :index, :limit => 2, :offset => 2)
|
155
|
+
@docs.size.should == 2
|
156
|
+
@docs.first[:index].should == 3
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should put in descending order' do
|
160
|
+
@docs = @design.query( :index, :order => :desc )
|
161
|
+
@docs.first[:index].should == 10
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should select a range' do
|
165
|
+
@docs = @design.query( :index, :range => [2,4])
|
166
|
+
@docs.size.should == 3
|
167
|
+
@docs.first[:index].should == 2
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should select a range with descending order' do
|
171
|
+
@docs = @design.query( :index, :range => [2,4], :order => :descending )
|
172
|
+
@docs.size.should == 3
|
173
|
+
@docs.first[:index].should == 4
|
174
|
+
@docs[2][:index].should == 2
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should select by exact key' do
|
178
|
+
@docs = @design.query( :index, :equals => 3 )
|
179
|
+
@docs.size.should == 1
|
180
|
+
@docs.first[:index].should == 3
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
43
184
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
Aqua.set_storage_engine('CouchDB') # to initialize the Aqua::Store namespace
|
4
|
+
|
5
|
+
# Conveniences for typing with tests ...
|
6
|
+
CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
7
|
+
Database = CouchDB::Database unless defined?( Database )
|
8
|
+
Design = CouchDB::DesignDocument unless defined?( Design )
|
9
|
+
ResultSet = CouchDB::ResultSet unless defined?( ResultSet )
|
10
|
+
|
11
|
+
require File.dirname(__FILE__) + '/fixtures_and_data/document_fixture' # Document ... a Mash with the collection of methods
|
12
|
+
class Docintalk < Document
|
13
|
+
def talk
|
14
|
+
'Hello, I am a Docintalk'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ResultSet do
|
19
|
+
before(:each) do
|
20
|
+
ResultSet.document_class = nil # resets for all theses tests
|
21
|
+
# These are sample returns from couchdb for a view query
|
22
|
+
# the first is when the include_document=true is omitted
|
23
|
+
# the next is when it is included
|
24
|
+
@no_docs = {
|
25
|
+
"rows"=>[
|
26
|
+
{"id"=>"b7e4623f506c437bae2b517d169b3c88", "value"=>nil, "key"=>1},
|
27
|
+
{"id"=>"43d650760fdda785a3bd20056d53b3e0", "value"=>nil, "key"=>2},
|
28
|
+
{"id"=>"b638586d7d71267e54af9420ee803a7c", "value"=>nil, "key"=>3},
|
29
|
+
{"id"=>"c0f8a9d683fb1576dc1da943d9bf2251", "value"=>nil, "key"=>4},
|
30
|
+
{"id"=>"11d12976059170f360df222bc097834c", "value"=>nil, "key"=>5},
|
31
|
+
{"id"=>"d9270a9bdc7128f02c4b9ccdc10e6b18", "value"=>nil, "key"=>6},
|
32
|
+
{"id"=>"c85c7d08e240c1798a7db11b0756581c", "value"=>nil, "key"=>7},
|
33
|
+
{"id"=>"721ec0ec55c5d16719ae438855528575", "value"=>nil, "key"=>8},
|
34
|
+
{"id"=>"13d2140c707196af4b4e53fe73a0ab0b", "value"=>nil, "key"=>9},
|
35
|
+
{"id"=>"b139683cf575446edb4245eba245d907", "value"=>nil, "key"=>10}
|
36
|
+
],
|
37
|
+
"offset"=>0,
|
38
|
+
"total_rows"=>10
|
39
|
+
}
|
40
|
+
@with_docs = {
|
41
|
+
"rows"=>[
|
42
|
+
{"doc"=>{"_id"=>"9d749a8a532294c22ccbf16873f50ead", "_rev"=>"1-567432465", "index"=>2}, "id"=>"9d749a8a532294c22ccbf16873f50ead", "value"=>nil, "key"=>1},
|
43
|
+
{"doc"=>{"_id"=>"b1394da1469eae862cca661da238b951", "_rev"=>"1-2128259075", "index"=>3}, "id"=>"b1394da1469eae862cca661da238b951", "value"=>nil, "key"=>2},
|
44
|
+
{"doc"=>{"_id"=>"a1b7b978b20649cb5fd648cd510e0243", "_rev"=>"1-3326711422", "index"=>4}, "id"=>"a1b7b978b20649cb5fd648cd510e0243", "value"=>nil, "key"=>3},
|
45
|
+
{"doc"=>{"_id"=>"92b69da432d658da6dc69a5c611065ca", "_rev"=>"1-2590331142", "index"=>5}, "id"=>"92b69da432d658da6dc69a5c611065ca", "value"=>nil, "key"=>4},
|
46
|
+
{"doc"=>{"_id"=>"f3b257b6d9bc60062147db98175a809b", "_rev"=>"1-2121844908", "index"=>6}, "id"=>"f3b257b6d9bc60062147db98175a809b", "value"=>nil, "key"=>5},
|
47
|
+
],
|
48
|
+
"offset"=>1,
|
49
|
+
"total_rows"=>5
|
50
|
+
}
|
51
|
+
@docless = ResultSet.new( @no_docs )
|
52
|
+
@docfull = ResultSet.new( @with_docs )
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should have a default document class accessor' do
|
56
|
+
ResultSet.should respond_to(:document_class)
|
57
|
+
ResultSet.should respond_to(:document_class=)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should have an offset' do
|
61
|
+
@docless.offset.should == 0
|
62
|
+
@docfull.offset.should == 1
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should have a total' do
|
66
|
+
@docless.total.should == 10
|
67
|
+
@docfull.total.should == 5
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should have rows' do
|
71
|
+
@docless.rows.should == @no_docs['rows']
|
72
|
+
@docfull.rows.should == @with_docs['rows']
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'keys should be the array accessible content of the set when docs are not included' do
|
76
|
+
@docless.first.should == @no_docs['rows'].first['key']
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'docs should be the array accessible content of the set, when available' do
|
80
|
+
@docfull.first.should == @with_docs['rows'].first['doc']
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'it should convert docs to the default document class if no instance level document class is available' do
|
84
|
+
ResultSet.document_class = Document
|
85
|
+
docs = ResultSet.new( @with_docs )
|
86
|
+
docs.first.class.should == Document
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should use instance level document class when available' do
|
90
|
+
docs = ResultSet.new( @with_docs, Docintalk )
|
91
|
+
docs.document_class.should == Docintalk
|
92
|
+
docs.first.class.should == Docintalk
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -4,10 +4,10 @@ Aqua.set_storage_engine('CouchDB') # to initialize the Aqua::Store namespace
|
|
4
4
|
require File.dirname(__FILE__) + '/fixtures_and_data/document_fixture' # Document ... a Mash with the collection of methods
|
5
5
|
|
6
6
|
# Conveniences for typing with tests ...
|
7
|
-
CouchDB = Aqua::Store::CouchDB
|
8
|
-
Database = CouchDB::Database
|
9
|
-
Server = CouchDB::Server
|
10
|
-
Attachments = CouchDB::Attachments
|
7
|
+
CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
8
|
+
Database = CouchDB::Database unless defined?( Database )
|
9
|
+
Server = CouchDB::Server unless defined?( Server)
|
10
|
+
Attachments = CouchDB::Attachments unless defined?( Attachments )
|
11
11
|
|
12
12
|
describe 'CouchDB::StorageMethods' do
|
13
13
|
before(:each) do
|
@@ -17,6 +17,9 @@ describe 'CouchDB::StorageMethods' do
|
|
17
17
|
:more => "my big stuff"
|
18
18
|
}
|
19
19
|
@doc = Document.new( @params )
|
20
|
+
# the line below is neccessary in the full suite, but not when the file is run on it's own ??
|
21
|
+
CouchDB.put( 'http://127.0.0.1:5984/aqua' ) unless @doc.class.database.exists?
|
22
|
+
@doc.class.database.delete_all
|
20
23
|
end
|
21
24
|
|
22
25
|
describe 'initialization' do
|
@@ -148,10 +151,6 @@ describe 'CouchDB::StorageMethods' do
|
|
148
151
|
end
|
149
152
|
|
150
153
|
describe 'save/create' do
|
151
|
-
before(:each) do
|
152
|
-
@doc.delete if @doc.exists?
|
153
|
-
end
|
154
|
-
|
155
154
|
it 'saving should create a document in the database' do
|
156
155
|
@doc.save
|
157
156
|
lambda{ Aqua::Store::CouchDB.get( @doc.uri ) }.should_not raise_error
|
@@ -213,9 +212,43 @@ describe 'CouchDB::StorageMethods' do
|
|
213
212
|
@doc[:noodle] = 'spaghetti'
|
214
213
|
@doc.reload
|
215
214
|
@doc[:noodle].should be_nil
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should create using find_or_create' do
|
218
|
+
lambda{ Document.get( @params[:id] ) }.should raise_error
|
219
|
+
doc = Document.find_or_create( @params[:id] )
|
220
|
+
lambda{ Document.get( @params[:id] ) }.should_not raise_error
|
216
221
|
end
|
217
222
|
end
|
218
223
|
|
224
|
+
describe 'getting' do
|
225
|
+
it 'should get a document from its id' do
|
226
|
+
@doc.save!
|
227
|
+
lambda{ Document.get( @doc.id ) }.should_not raise_error
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'returned document should have an id' do
|
231
|
+
@doc.save!
|
232
|
+
document = Document.get( @doc.id )
|
233
|
+
document.id.should == @doc.id
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'returned document should have an id even if not explicitly set' do
|
237
|
+
doc = Document.new(:this => 'that')
|
238
|
+
doc.save!
|
239
|
+
retrieved = Document.get( doc.id )
|
240
|
+
retrieved.id.should_not be_nil
|
241
|
+
retrieved.id.should_not be_empty
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'returned document should have a rev' do
|
245
|
+
@doc.save!
|
246
|
+
document = Document.get( @doc.id )
|
247
|
+
document.rev.should_not be_nil
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
219
252
|
describe 'deleting' do
|
220
253
|
before(:each) do
|
221
254
|
@doc.delete if @doc.exists?
|
@@ -401,8 +434,115 @@ describe 'CouchDB::StorageMethods' do
|
|
401
434
|
|
402
435
|
end
|
403
436
|
|
404
|
-
describe '
|
405
|
-
it 'should '
|
437
|
+
describe 'design document' do
|
438
|
+
it 'should not have a design document if there is no design_name' do
|
439
|
+
Document.design_name.should be_nil
|
440
|
+
Document.design_document.should be_nil
|
441
|
+
end
|
442
|
+
|
443
|
+
it 'should create a design document if there is a design_name but the design document exists' do
|
444
|
+
Document.design_name = 'User'
|
445
|
+
lambda{ CouchDB::DesignDocument.get( 'User' ) }.should raise_error
|
446
|
+
Document.design_document.should_not be_nil
|
447
|
+
lambda{ CouchDB::DesignDocument.get( 'User') }.should_not raise_error
|
448
|
+
end
|
449
|
+
|
450
|
+
it 'should retrieve a design document if there is a design_name and the design document exists' do
|
451
|
+
CouchDB::DesignDocument.create!( :name => 'User' )
|
452
|
+
# ensures that the record exists, before the real test
|
453
|
+
lambda{ CouchDB::DesignDocument.get( 'User') }.should_not raise_error
|
454
|
+
Document.design_document.should_not be_nil
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
describe 'indexing & queries' do
|
459
|
+
Document.class_eval { attr_accessor( :my_field ) }
|
460
|
+
|
461
|
+
it 'should have a class method "indexes" that stores map names related to the class' do
|
462
|
+
Document.indexes.should == []
|
463
|
+
end
|
464
|
+
|
465
|
+
describe 'index_on' do
|
466
|
+
before(:each) do
|
467
|
+
Document.index_on(:my_field)
|
468
|
+
end
|
469
|
+
|
470
|
+
it 'should add text and symbol entries to indexes' do
|
471
|
+
Document.indexes.size.should == 2
|
472
|
+
Document.indexes.should include( :my_field )
|
473
|
+
Document.indexes.should include( 'my_field' )
|
474
|
+
end
|
475
|
+
|
476
|
+
it 'should not duplicate an index name' do
|
477
|
+
# previous tests have already added it to the array
|
478
|
+
Document.indexes.size.should == 2
|
479
|
+
end
|
480
|
+
|
481
|
+
it 'should add a view to the design document' do
|
482
|
+
design = Document.design_document(true)
|
483
|
+
design.views.should include( :my_field )
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
describe 'queries' do
|
488
|
+
before(:each) do
|
489
|
+
Document.parent_class = 'Document'
|
490
|
+
Document.index_on(:my_field)
|
491
|
+
Document.index_on_ivar( :my_ivar )
|
492
|
+
(1..5).each do |number|
|
493
|
+
Document.create!(
|
494
|
+
:my_field => number * 5,
|
495
|
+
:ivars => {
|
496
|
+
'@my_ivar' => number + 5
|
497
|
+
},
|
498
|
+
:class => 'Document'
|
499
|
+
)
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
it 'should query full documents for an index' do
|
504
|
+
docs = Document.query(:my_field)
|
505
|
+
docs.each{ |r| r.class.should == Document }
|
506
|
+
docs.size.should == 5
|
507
|
+
end
|
508
|
+
|
509
|
+
it 'should query ivar indexes correctly' do
|
510
|
+
docs = Document.query(:my_ivar)
|
511
|
+
docs.each{ |r| r.class.should == Document }
|
512
|
+
docs.size.should == 5
|
513
|
+
end
|
514
|
+
|
515
|
+
it 'should query only the index value for an index' do
|
516
|
+
docs = Document.query(:my_field, :select => 'index only')
|
517
|
+
docs.each{ |r| r.class.should == Fixnum }
|
518
|
+
end
|
519
|
+
|
520
|
+
it 'should generate a calculated/reduced view for an index the first time it is called' do
|
521
|
+
Document.count(:my_field)
|
522
|
+
Document.design_document.views.should include( :my_field_count )
|
523
|
+
end
|
524
|
+
|
525
|
+
it 'should count an index' do
|
526
|
+
Document.count(:my_field).should == 5
|
527
|
+
end
|
528
|
+
|
529
|
+
it 'should sum an index' do
|
530
|
+
Document.sum(:my_field).should == 75
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'should average an index' do
|
534
|
+
Document.average(:my_field).should == 15
|
535
|
+
end
|
536
|
+
|
537
|
+
it 'should get the minimum of an index' do
|
538
|
+
Document.min(:my_field).should == 5
|
539
|
+
end
|
540
|
+
|
541
|
+
it 'should get the maximum of an index' do
|
542
|
+
Document.max(:my_field).should == 25
|
543
|
+
end
|
544
|
+
|
545
|
+
end
|
406
546
|
end
|
407
547
|
|
408
548
|
end
|