couchdb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+
2
+ module CouchDB
3
+
4
+ # The Row class acts as a wrapper for a CouchDB view result row.
5
+ class Row
6
+
7
+ attr_reader :database
8
+ attr_reader :id
9
+ attr_reader :key
10
+ attr_reader :value
11
+
12
+ def initialize(database, attributes = { })
13
+ @database, @id, @key, @value, @document = database, *attributes.values_at("id", "key", "value", "doc")
14
+ end
15
+
16
+ def document
17
+ Document.new @database, @document
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,42 @@
1
+
2
+ module CouchDB
3
+
4
+ # The Server class provides methods to retrieve informations and statistics
5
+ # of a CouchDB server.
6
+ class Server
7
+
8
+ attr_reader :host
9
+ attr_reader :port
10
+
11
+ def initialize(host = "localhost", port = 5984)
12
+ @host, @port = host, port
13
+ end
14
+
15
+ def ==(other)
16
+ other.is_a?(self.class) && @host == other.host && @port == other.port
17
+ end
18
+
19
+ def information
20
+ Transport::JSON.request :get, url + "/", :expected_status_code => 200
21
+ end
22
+
23
+ def statistics
24
+ Transport::JSON.request :get, url + "/_stats", :expected_status_code => 200
25
+ end
26
+
27
+ def database_names
28
+ Transport::JSON.request :get, url + "/_all_dbs", :expected_status_code => 200
29
+ end
30
+
31
+ def uuids(count = 1)
32
+ response = Transport::JSON.request :get, url + "/_uuids", :expected_status_code => 200, :parameters => { :count => count }
33
+ response["uuids"]
34
+ end
35
+
36
+ def url
37
+ "http://#{@host}:#{@port}"
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,56 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe CouchDB::Database do
4
+
5
+ before :each do
6
+ @server = CouchDB::Server.new
7
+ @database = described_class.new @server, "test"
8
+ end
9
+
10
+ describe "create!" do
11
+
12
+ before :each do
13
+ @database.delete_if_exists!
14
+ end
15
+
16
+ it "should create the database" do
17
+ @database.create!
18
+ @database.exists?.should be_true
19
+ end
20
+
21
+ end
22
+
23
+ describe "delete!" do
24
+
25
+ before :each do
26
+ @database.create_if_missing!
27
+ end
28
+
29
+ it "should delete the database" do
30
+ @database.delete!
31
+ @database.exists?.should be_false
32
+ end
33
+
34
+ end
35
+
36
+ describe "information" do
37
+
38
+ before :each do
39
+ @database.create_if_missing!
40
+ end
41
+
42
+ it "should return information about the database" do
43
+ @database.information.should be_instance_of(Hash)
44
+ end
45
+
46
+ end
47
+
48
+ describe "documents" do
49
+
50
+ it "should return a collection" do
51
+ @database.documents.should be_instance_of(CouchDB::Collection)
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,78 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe CouchDB::Document do
4
+
5
+ before :each do
6
+ @server = CouchDB::Server.new
7
+ @database = CouchDB::Database.new @server, "test"
8
+ @database.delete_if_exists!
9
+ @database.create_if_missing!
10
+
11
+ @document = described_class.new @database, "_id" => "test_document_1", "test" => "test value"
12
+ @document.save
13
+ end
14
+
15
+ after :each do
16
+ @document.destroy
17
+ end
18
+
19
+ describe "load" do
20
+
21
+ it "should load the document's properties" do
22
+ @document["test"] = nil
23
+ @document.load
24
+ @document["test"].should == "test value"
25
+ end
26
+
27
+ end
28
+
29
+ describe "save" do
30
+
31
+ context "on a new model" do
32
+
33
+ before :each do
34
+ begin
35
+ @document.load
36
+ @document.destroy
37
+ rescue described_class::NotFoundError
38
+ end
39
+ end
40
+
41
+ it "should create the document" do
42
+ lambda do
43
+ @document.save
44
+ end.should change(@document, :new?).from(true).to(false)
45
+ end
46
+
47
+ end
48
+
49
+ context "on an existing model" do
50
+
51
+ it "should update the document" do
52
+ lambda do
53
+ @document["test"] = "another test value"
54
+ @document.save
55
+ end.should change(@document, :rev)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ describe "destroy" do
63
+
64
+ it "should destroy the document" do
65
+ lambda do
66
+ @document.destroy
67
+ end.should change(@document, :exists?).from(true).to(false)
68
+ end
69
+
70
+ it "should set the document's state to new" do
71
+ lambda do
72
+ @document.destroy
73
+ end.should change(@document, :new?).from(false).to(true)
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,43 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe CouchDB::Server do
4
+
5
+ before :each do
6
+ @server = described_class.new
7
+ end
8
+
9
+ describe "information" do
10
+
11
+ it "should return some information about the server" do
12
+ @server.information.should == { "couchdb" => "Welcome", "version" => "1.0.1" }
13
+ end
14
+
15
+ end
16
+
17
+ describe "statistics" do
18
+
19
+ it "should return some statistics about the server" do
20
+ @server.statistics.should be_instance_of(Hash)
21
+ end
22
+
23
+ end
24
+
25
+ describe "database_names" do
26
+
27
+ it "should return the names of all databases" do
28
+ @server.database_names.should be_instance_of(Array)
29
+ end
30
+
31
+ end
32
+
33
+ describe "uuids" do
34
+
35
+ it "should return the given number of generated uuids" do
36
+ uuids = @server.uuids 4
37
+ uuids.should be_instance_of(Array)
38
+ uuids.size.should == 4
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe "views" do
4
+
5
+ before :each do
6
+ @server = CouchDB::Server.new
7
+ @database = CouchDB::Database.new @server, "test"
8
+ @database.delete_if_exists!
9
+ @database.create_if_missing!
10
+
11
+ @document_one = CouchDB::Document.new @database, "_id" => "test_document_1", "category" => "one"
12
+ @document_one.save
13
+ @document_two = CouchDB::Document.new @database, "_id" => "test_document_2", "category" => "two"
14
+ @document_two.save
15
+
16
+ @design = CouchDB::Design.new @database, "design_1"
17
+ @view = CouchDB::Design::View.new @design, "view_1",
18
+ "function(document) { emit([ document['category'], document['_id'] ]); }"
19
+ @design.save
20
+ end
21
+
22
+ describe "collection" do
23
+
24
+ it "should return a collection including the right rows" do
25
+ collection = @view.collection :startkey => [ "one", nil ], :endkey => [ "one", { } ]
26
+ collection.size.should == 1
27
+ collection[0].id.should == "test_document_1"
28
+ collection[0].key.should == [ "one", "test_document_1" ]
29
+ collection[0].value.should be_nil
30
+ end
31
+
32
+ it "should return a collection including the right documents" do
33
+ collection = @view.collection :startkey => [ "one", nil ], :endkey => [ "one", { } ]
34
+ collection.documents.should include(@document_one)
35
+ collection.documents.should_not include(@document_two)
36
+ end
37
+
38
+ end
39
+
40
+ describe "all documents collection" do
41
+
42
+ it "should return a collection with all documents of the database" do
43
+ collection = @database.documents
44
+ collection.size.should == 3 # two documents plus the design
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+
3
+ describe CouchDB::Collection do
4
+
5
+ before :each do
6
+ Transport::JSON.stub(:request)
7
+ @database = mock CouchDB::Database
8
+
9
+ @collection = described_class.new @database, "http://host:1234/test/_all_docs"
10
+ end
11
+
12
+ describe "initialize" do
13
+
14
+ it "should set the database" do
15
+ @collection.database.should == @database
16
+ end
17
+
18
+ it "should set the url" do
19
+ @collection.url.should == "http://host:1234/test/_all_docs"
20
+ end
21
+
22
+ end
23
+
24
+ describe "total_count" do
25
+
26
+ before :each do
27
+ Transport::JSON.stub(:request).and_return({ "total_rows" => 1 })
28
+ end
29
+
30
+ describe "without a previously performed fetch" do
31
+
32
+ it "should perform a meta fetch (with a limit of zero)" do
33
+ Transport::JSON.should_receive(:request).with(
34
+ :get,
35
+ "http://host:1234/test/_all_docs",
36
+ :parameters => { :limit => 0 },
37
+ :encode_parameters => true,
38
+ :expected_status_code => 200
39
+ ).and_return({ "total_rows" => 1 })
40
+ @collection.total_count
41
+ end
42
+
43
+ it "should return the total count" do
44
+ @collection.total_count.should == 1
45
+ end
46
+
47
+ end
48
+
49
+ describe "with a previously performed fetch" do
50
+
51
+ before :each do
52
+ @collection.first # perform the fetch
53
+ end
54
+
55
+ it "should not perform another fetch" do
56
+ Transport::JSON.should_not_receive(:request)
57
+ @collection.total_count
58
+ end
59
+
60
+ it "should return the total count" do
61
+ @collection.total_count.should == 1
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ describe "first" do
69
+
70
+ before :each do
71
+ @row_hash = mock Hash
72
+ Transport::JSON.stub(:request).and_return({
73
+ "total_rows" => 1,
74
+ "rows" => [ @row_hash ]
75
+ })
76
+ @row = mock CouchDB::Row
77
+ CouchDB::Row.stub(:new).and_return(@row)
78
+ end
79
+
80
+ it "should initialize the row with the row hash" do
81
+ CouchDB::Row.should_receive(:new).with(@database, @row_hash).and_return(@row)
82
+ @collection.first
83
+ end
84
+
85
+ it "should return the first element of the fetched result" do
86
+ @collection.first.should == @row
87
+ end
88
+
89
+ it "should update the total count" do
90
+ @collection.first
91
+ @collection.total_count.should == 1
92
+ end
93
+
94
+ end
95
+
96
+ describe "documents" do
97
+
98
+ before :each do
99
+ @document = mock CouchDB::Document
100
+ @row = mock CouchDB::Row, :document => @document
101
+ @collection.stub(:map).and_yield(@row).and_return([ @document ])
102
+ end
103
+
104
+ it "should add the include docs options" do
105
+ @collection.documents.first
106
+ @collection.options.should include(:include_docs => true)
107
+ end
108
+
109
+ it "should map the rows to documents" do
110
+ @collection.should_receive(:map).and_yield(@row).and_return([ @document ])
111
+ @collection.documents.first
112
+ end
113
+
114
+ it "should return the selected row's document" do
115
+ document = @collection.documents.first
116
+ document.should == @document
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+
3
+ describe CouchDB::Database do
4
+
5
+ before :each do
6
+ Transport::JSON.stub(:request)
7
+ @server = mock CouchDB::Server, :url => "http://host:1234", :database_names => [ "test" ]
8
+
9
+ @database = CouchDB::Database.new @server, "test"
10
+ end
11
+
12
+ describe "==" do
13
+
14
+ it "should be true when comparing two equal databases" do
15
+ @database.should == described_class.new(@server, "test")
16
+ end
17
+
18
+ it "should be false when comparing two different databases" do
19
+ @database.should_not == described_class.new(@server, "different")
20
+ end
21
+
22
+ end
23
+
24
+ describe "===" do
25
+
26
+ it "should be true when comparing a database object with itself" do
27
+ @database.should === @database
28
+ end
29
+
30
+ it "should be false when comparing a database object with another database object" do
31
+ @database.should_not === described_class.new(@server, "test")
32
+ end
33
+
34
+ end
35
+
36
+ describe "create!" do
37
+
38
+ it "should request the create of the database" do
39
+ Transport::JSON.should_receive(:request).with(
40
+ :put,
41
+ "http://host:1234/test",
42
+ :expected_status_code => 201
43
+ )
44
+ @database.create!
45
+ end
46
+
47
+ end
48
+
49
+ describe "create_if_missing!" do
50
+
51
+ before :each do
52
+ @database.stub(:create!)
53
+ end
54
+
55
+ it "should not call create! if the database exists" do
56
+ @database.stub(:exists?).and_return(true)
57
+ @database.should_not_receive(:create!)
58
+ @database.create_if_missing!
59
+ end
60
+
61
+ it "should call create! if the database not exists" do
62
+ @database.stub(:exists?).and_return(false)
63
+ @database.should_receive(:create!)
64
+ @database.create_if_missing!
65
+ end
66
+
67
+ end
68
+
69
+ describe "delete!" do
70
+
71
+ it "should delete the database" do
72
+ Transport::JSON.should_receive(:request).with(
73
+ :delete,
74
+ "http://host:1234/test",
75
+ :expected_status_code => 200
76
+ )
77
+ @database.delete!
78
+ end
79
+
80
+ end
81
+
82
+ describe "delete_if_exists!" do
83
+
84
+ before :each do
85
+ @database.stub(:delete!)
86
+ end
87
+
88
+ it "should call delete! if the database exists" do
89
+ @database.stub(:exists?).and_return(true)
90
+ @database.should_receive(:delete!)
91
+ @database.delete_if_exists!
92
+ end
93
+
94
+ it "should not call delete! if the database not exists" do
95
+ @database.stub(:exists?).and_return(false)
96
+ @database.should_not_receive(:delete!)
97
+ @database.delete_if_exists!
98
+ end
99
+
100
+ end
101
+
102
+ describe "information" do
103
+
104
+ it "should request database information" do
105
+ Transport::JSON.should_receive(:request).with(
106
+ :get,
107
+ "http://host:1234/test",
108
+ :expected_status_code => 200
109
+ ).and_return("result")
110
+ @database.information.should == "result"
111
+ end
112
+
113
+ end
114
+
115
+ describe "exists?" do
116
+
117
+ it "should be true" do
118
+ @database.exists?.should be_true
119
+ end
120
+
121
+ it "should be false if no database with the given name exists" do
122
+ database = described_class.new @server, "invalid"
123
+ database.exists?.should be_false
124
+ end
125
+
126
+ end
127
+
128
+ describe "documents" do
129
+
130
+ it "should return a collection" do
131
+ collection = @database.documents
132
+ collection.should be_instance_of(CouchDB::Collection)
133
+ collection.url.should == "http://host:1234/test/_all_docs"
134
+ end
135
+
136
+ end
137
+
138
+ end