couchbase 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ {
2
+ "_id": "_design/test_it_creates_design_doc_from_io",
3
+ "language": "javascript",
4
+ "views": {
5
+ "all": {
6
+ "map": "function(doc){ if(doc.msg){ emit(doc._id, doc.msg) } }"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestBucket < MiniTest::Unit::TestCase
4
+ def setup
5
+ config_fixture = json_fixture('buckets-config.json')
6
+ Couchbase::Bucket.any_instance.stubs(:http_get).returns(config_fixture)
7
+ Couchbase::Bucket.class_eval do
8
+ alias :listen_for_config_changes_orig :listen_for_config_changes
9
+ define_method :listen_for_config_changes do
10
+ setup(config_fixture.first)
11
+ end
12
+ end
13
+ end
14
+
15
+ def teardown
16
+ Couchbase::Bucket.class_eval do
17
+ alias :listen_for_config_changes :listen_for_config_changes_orig
18
+ end
19
+ end
20
+
21
+ def test_it_should_defaults_to_default_bucket_in_production_mode
22
+ bucket = Couchbase.new('http://localhost:8091/pools/default')
23
+ assert_equal 'default', bucket.name
24
+ assert_equal :production, bucket.environment
25
+ end
26
+
27
+ def test_it_should_initialize_itself_from_config
28
+ bucket = Couchbase.new('http://localhost:8091/pools/default')
29
+ assert_equal 'http://localhost:8091/pools/default/buckets/default', bucket.uri.to_s
30
+ assert_equal 'membase', bucket.type
31
+ assert_equal 1, bucket.nodes.size
32
+ assert_equal 256, bucket.vbuckets.size
33
+ end
34
+
35
+ def test_initialization_low_level_drivers
36
+ bucket = Couchbase.new('http://localhost:8091/pools/default', :format => :plain)
37
+ assert_equal :plain, bucket.default_format
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestCouchbase < MiniTest::Unit::TestCase
4
+ def test_that_it_create_instance_of_bucket
5
+ assert_instance_of Couchbase::Bucket, Couchbase.new('http://localhost:8091/pools/default')
6
+ end
7
+ end
8
+
9
+
@@ -0,0 +1,98 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestCouchdb < MiniTest::Unit::TestCase
4
+ def setup
5
+ @bucket = Couchbase.new('http://localhost:8091/pools/default')
6
+ end
7
+
8
+ def test_that_it_could_connect_to_couchdb
9
+ server_uri = @bucket.next_node.couch_api_base[/http:\/\/[^\/]+/]
10
+ assert_equal %w(couchbase couchdb version), @bucket.http_get(server_uri).keys.sort
11
+ end
12
+
13
+ def test_that_it_raises_error_if_couch_api_isnt_implemented
14
+ bucket = Couchbase.new('http://localhost:8091/pools/default')
15
+ bucket.nodes.each{|node| node.couch_api_base = nil}
16
+ assert_raises(Couchbase::NotImplemented) do
17
+ bucket.design_docs
18
+ end
19
+ end
20
+
21
+ def test_that_it_could_create_doc_using_memcached_api
22
+ # cleanup
23
+ @bucket.delete(test_id) rescue Memcached::NotFound
24
+ @bucket.delete_design_doc(test_id)
25
+
26
+ @bucket[test_id] = {'msg' => 'hello world'}
27
+ @bucket.save_design_doc('_id' => "_design/#{test_id}",
28
+ 'views' => {'all' => {'map' => 'function(doc){if(doc.msg){emit(doc._id, doc.msg)}}'}})
29
+ assert_operation_completed { database_ready(@bucket) }
30
+ ddoc = @bucket.design_docs[test_id]
31
+ assert ddoc, "design document '_design/#{test_id}' not found"
32
+ doc = ddoc.all.detect{|doc| doc['id'] == test_id && doc['value'] == 'hello world'}
33
+ assert doc, "object '#{test_id}' not found"
34
+ end
35
+
36
+ def test_that_it_could_remove_design_doc
37
+ @bucket.delete_design_doc(test_id)
38
+ @bucket[test_id] = {'msg' => 'hello world'}
39
+ @bucket.save_design_doc('_id' => "_design/#{test_id}",
40
+ 'views' => {'all' => {'map' => 'function(doc){if(doc.msg){emit(doc._id, doc.msg)}}'}})
41
+ assert_operation_completed { database_ready(@bucket) }
42
+ ddoc = @bucket.design_docs[test_id]
43
+ assert ddoc, "design document '_design/#{test_id}' not found"
44
+ @bucket.delete_design_doc("_design/#{test_id}")
45
+ ddoc = @bucket.design_docs[test_id]
46
+ refute ddoc, "design document '_design/#{test_id}' still here"
47
+ end
48
+
49
+ def test_it_creates_design_doc_from_string
50
+ doc = <<-EOD
51
+ {
52
+ "_id": "_design/#{test_id}",
53
+ "language": "javascript",
54
+ "views": {
55
+ "all": {
56
+ "map": "function(doc){ if(doc.msg){ emit(doc._id, doc.msg) } }"
57
+ }
58
+ }
59
+ }
60
+ EOD
61
+
62
+ @bucket.delete_design_doc(test_id)
63
+ @bucket.save_design_doc(doc)
64
+ assert_operation_completed { database_ready(@bucket) }
65
+ assert @bucket.design_docs[test_id], "design document '_design/#{test_id}' not found"
66
+ end
67
+
68
+ def test_it_creates_design_doc_from_io
69
+ doc = File.open(File.join(File.dirname(__FILE__), 'support', 'sample_design_doc.json'))
70
+ @bucket.delete_design_doc(test_id)
71
+ @bucket.save_design_doc(doc)
72
+ assert_operation_completed { database_ready(@bucket) }
73
+ assert @bucket.design_docs[test_id], "design document '_design/#{test_id}' not found"
74
+ end
75
+
76
+ def test_it_creates_design_doc_from_hash
77
+ doc = {
78
+ "_id" => "_design/#{test_id}",
79
+ "language" => "javascript",
80
+ "views" => {
81
+ "all" => {
82
+ "map" => "function(doc){ if(doc.msg){ emit(doc._id, doc.msg) } }"
83
+ }
84
+ }
85
+ }
86
+
87
+ @bucket.delete_design_doc(test_id)
88
+ @bucket.save_design_doc(doc)
89
+ assert_operation_completed { database_ready(@bucket) }
90
+ assert @bucket.design_docs[test_id], "design document '_design/#{test_id}' not found"
91
+ end
92
+
93
+ protected
94
+
95
+ def test_id
96
+ name = caller.first[/.*[` ](.*)'/, 1]
97
+ end
98
+ end
@@ -0,0 +1,11 @@
1
+ require 'minitest/autorun'
2
+ require 'couchbase'
3
+
4
+ class TestView < MiniTest::Unit::TestCase
5
+ def test_that_it_defines_views_for_design_documents_only
6
+ design_doc = Couchbase::Document.new(:mock, {'_id' => '_design/foo', 'views' => {'all' => {'map' => 'function(doc){}'}}})
7
+ assert_respond_to(design_doc, :all)
8
+ regular_doc = Couchbase::Document.new(:mock, {'_id' => 'foo', 'views' => {'all' => {'map' => 'function(doc){}'}}})
9
+ refute_respond_to(regular_doc, :all)
10
+ end
11
+ end
@@ -0,0 +1,88 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestLatch < MiniTest::Unit::TestCase
4
+ def test_properly_initialize
5
+ l = Couchbase::Latch.new(true, false)
6
+ assert_equal(true, l.state)
7
+ assert_equal(false, l.target)
8
+ end
9
+
10
+ def test_basic_latch_usage
11
+ latch = Couchbase::Latch.new(:dirty, :ready)
12
+ obj = "bar"
13
+ Thread.new do
14
+ obj = "foo"
15
+ latch.toggle
16
+ end
17
+ latch.wait
18
+ assert_equal(:ready, latch.state)
19
+ assert_equal("foo", obj)
20
+ end
21
+
22
+ def test_basic_latch_usage_inverted
23
+ latch = Couchbase::Latch.new(:dirty, :ready)
24
+ obj = "bar"
25
+ Thread.new do
26
+ latch.wait
27
+ assert_equal(:ready, latch.state)
28
+ assert_equal("foo", obj)
29
+ end
30
+ obj = "foo"
31
+ latch.toggle
32
+ end
33
+
34
+ def test_latch_with_identical_values_skips_wait
35
+ latch = Couchbase::Latch.new(:ready, :ready)
36
+ latch.wait
37
+ assert_equal(:ready, latch.state)
38
+ end
39
+
40
+ def test_toggle_with_two_chained_threads
41
+ latch = Couchbase::Latch.new(:start, :end)
42
+ name = "foo"
43
+ Thread.new do
44
+ Thread.new do
45
+ name = "bar"
46
+ latch.toggle
47
+ end
48
+ end
49
+ latch.wait
50
+ assert_equal(:end, latch.state)
51
+ assert_equal("bar", name)
52
+ end
53
+
54
+ def test_toggle_with_multiple_waiters
55
+ proceed_latch = Couchbase::Latch.new(:start, :end)
56
+ result = :bar
57
+ Thread.new do
58
+ proceed_latch.wait
59
+ assert_equal(:foo, result)
60
+ end
61
+ Thread.new do
62
+ proceed_latch.wait
63
+ assert_equal(:foo, result)
64
+ end
65
+ assert_equal(:bar, result)
66
+ proceed_latch.toggle
67
+ assert_equal(:end, proceed_latch.state)
68
+ end
69
+
70
+ def test_interleaved_latches
71
+ check_latch = Couchbase::Latch.new(:dirty, :ready)
72
+ change_1_latch = Couchbase::Latch.new(:dirty, :ready)
73
+ change_2_latch = Couchbase::Latch.new(:dirty, :ready)
74
+ name = "foo"
75
+ Thread.new do
76
+ name = "bar"
77
+ change_1_latch.toggle
78
+ check_latch.wait
79
+ name = "man"
80
+ change_2_latch.toggle
81
+ end
82
+ change_1_latch.wait
83
+ assert_equal("bar", name)
84
+ check_latch.toggle
85
+ change_2_latch.wait
86
+ assert_equal("man", name)
87
+ end
88
+ end
@@ -0,0 +1,59 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestMemcached < MiniTest::Unit::TestCase
4
+
5
+ def test_race_absence_during_initialization
6
+ session = connect
7
+ assert_raises(Memcached::NotFound) do
8
+ session.get(test_id)
9
+ end
10
+ end
11
+
12
+ def test_experimental_features_is_always_on
13
+ assert_respond_to connect, :touch
14
+ assert_respond_to connect(:experimental_features => false), :touch
15
+ assert_respond_to connect('experimental_features' => false), :touch
16
+ end
17
+
18
+ def test_single_get
19
+ session = connect
20
+ session.set(test_id, "foo")
21
+ assert "foo", session.get(test_id)
22
+ end
23
+
24
+ def test_single_get_missing
25
+ assert_raises(Memcached::NotFound) do
26
+ connect.get("missing-key")
27
+ end
28
+ end
29
+
30
+ def test_multi_get
31
+ session = connect
32
+ session.set(test_id(1), "foo")
33
+ session.set(test_id(2), "bar")
34
+ expected = {test_id(1) => "foo", test_id(2) => "bar"}
35
+ assert expected, session.get(test_id(1), test_id(2))
36
+ ids = [1, 2].map{|n| test_id(n)}
37
+ assert expected, session.get(ids)
38
+ end
39
+
40
+ def test_multi_get_missing
41
+ session = connect
42
+ session.set(test_id(1), "foo")
43
+ expected = {test_id(1) => "foo"}
44
+ assert expected, session.get(test_id(1), test_id(2))
45
+ ids = [1, 2].map{|n| test_id(n)}
46
+ assert expected, session.get(ids)
47
+ end
48
+
49
+ protected
50
+
51
+ def connect(options = {})
52
+ uri = options.delete(:pool_uri) || "http://localhost:8091/pools/default"
53
+ Couchbase.new(uri, options)
54
+ end
55
+
56
+ def test_id(suffix = nil)
57
+ "#{caller.first[/.*[` ](.*)'/, 1]}#{suffix}"
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ require 'minitest/autorun'
2
+ require 'couchbase'
3
+
4
+ class TestRestClient < MiniTest::Unit::TestCase
5
+ class RestClientMock
6
+ extend Couchbase::RestClient
7
+ end
8
+
9
+ def test_that_build_uri_duplicates_string
10
+ uri = "http://example.com/"
11
+ assert_equal "http://example.com/?foo=bar", RestClientMock.send(:build_query, uri, {'foo' => 'bar'})
12
+ assert_equal "http://example.com/", uri
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestVersion < MiniTest::Unit::TestCase
4
+ def test_that_it_defines_version
5
+ assert_match /\d+\.\d+(\.\d*)/, Couchbase::VERSION
6
+ end
7
+ end
@@ -0,0 +1,98 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestView < MiniTest::Unit::TestCase
4
+ def test_pagination
5
+ connection = populate_database
6
+ view = connection.design_docs['test_view'].all
7
+
8
+ # fetch all records
9
+ collection = view.fetch(:limit => 10)
10
+ assert_equal 10, collection.size
11
+ assert_equal 100, collection.total_entries
12
+
13
+ # fetch with reduce
14
+ view = connection.design_docs['test_view'].sum
15
+ docs = view.fetch(:limit => 2, :group => true)
16
+ assert_equal 2, docs.size
17
+ assert_equal nil, docs.total_entries
18
+
19
+ assert_instance_of Couchbase::View, connection.all_docs
20
+ end
21
+
22
+ def test_when_stream_has_errors_it_raises_error_by_default
23
+ response = <<-EOR
24
+ {
25
+ "total_rows": 0,
26
+ "rows": [ ],
27
+ "errors": [
28
+ {
29
+ "from": "127.0.0.1:5984",
30
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_b`."
31
+ },
32
+ {
33
+ "from": "http:// localhost:5984/_view_merge/",
34
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_c`."
35
+ }
36
+ ]
37
+ }
38
+ EOR
39
+ view = Couchbase::View.new(stub(:curl_easy => response),
40
+ "http://localhost:5984/default/_design/test/_view/all")
41
+ assert_raises(Couchbase::ViewError) do
42
+ view.fetch
43
+ end
44
+ end
45
+
46
+ def test_when_stream_has_errors_and_error_callback_provided_it_executes_the_callback
47
+ response = <<-EOR
48
+ {
49
+ "total_rows": 0,
50
+ "rows": [ ],
51
+ "errors": [
52
+ {
53
+ "from": "127.0.0.1:5984",
54
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_b`."
55
+ },
56
+ {
57
+ "from": "http:// localhost:5984/_view_merge/",
58
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_c`."
59
+ }
60
+ ]
61
+ }
62
+ EOR
63
+ view = Couchbase::View.new(stub(:curl_easy => response),
64
+ "http://localhost:5984/default/_design/test/_view/all")
65
+ errcount = 0
66
+ view.on_error{|from, reason| errcount += 1}
67
+ view.fetch
68
+ assert 2, errcount
69
+ end
70
+
71
+ protected
72
+
73
+ def populate_database
74
+ connection = Couchbase.new('http://localhost:8091/pools/default')
75
+ # clear storage
76
+ connection.flush
77
+ # save 100 documents
78
+ toys = %w(buzz rex bo hamm slink potato)
79
+ 100.times do |t|
80
+ connection["test_view_#{t}"]= {:counter => t+1, :toy => toys[t%6]}
81
+ end
82
+
83
+ connection.delete_design_doc('test_view')
84
+ connection.save_design_doc('_id' => '_design/test_view',
85
+ 'views' => {
86
+ 'all' => {'map' => 'function(doc){if(doc.counter){emit(doc._id, doc)}}'},
87
+ 'sum' => {'map' => 'function(doc){if(doc.counter){emit(doc.toy, doc.counter)}}',
88
+ 'reduce' => 'function(keys,values,rereduce){return sum(values)}'}})
89
+
90
+ assert connection.design_docs['test_view']
91
+
92
+ assert_operation_completed do
93
+ database_ready(connection) && connection.all_docs.count > 100
94
+ end
95
+ connection
96
+ end
97
+
98
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: couchbase
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Couchbase
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-05 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: memcached
16
+ requirement: &21810440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *21810440
25
+ - !ruby/object:Gem::Dependency
26
+ name: yajl-ruby
27
+ requirement: &21809260 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *21809260
36
+ - !ruby/object:Gem::Dependency
37
+ name: curb
38
+ requirement: &21808520 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.7.15
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *21808520
47
+ - !ruby/object:Gem::Dependency
48
+ name: yaji
49
+ requirement: &21807740 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.9
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *21807740
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &21807100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *21807100
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: &21806400 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *21806400
80
+ - !ruby/object:Gem::Dependency
81
+ name: mocha
82
+ requirement: &21805980 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *21805980
91
+ description: The official client library for use with Couchbase Server.
92
+ email: info@couchbase.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - .gitignore
98
+ - Gemfile
99
+ - HISTORY.markdown
100
+ - LICENSE
101
+ - README.markdown
102
+ - Rakefile
103
+ - couchbase.gemspec
104
+ - lib/couchbase.rb
105
+ - lib/couchbase/bucket.rb
106
+ - lib/couchbase/couchdb.rb
107
+ - lib/couchbase/document.rb
108
+ - lib/couchbase/http_status.rb
109
+ - lib/couchbase/latch.rb
110
+ - lib/couchbase/memcached.rb
111
+ - lib/couchbase/node.rb
112
+ - lib/couchbase/rest_client.rb
113
+ - lib/couchbase/version.rb
114
+ - lib/couchbase/view.rb
115
+ - test/setup.rb
116
+ - test/support/buckets-config.json
117
+ - test/support/sample_design_doc.json
118
+ - test/test_bucket.rb
119
+ - test/test_couchbase.rb
120
+ - test/test_couchdb.rb
121
+ - test/test_document.rb
122
+ - test/test_latch.rb
123
+ - test/test_memcached.rb
124
+ - test/test_rest_client.rb
125
+ - test/test_version.rb
126
+ - test/test_view.rb
127
+ homepage: http://couchbase.org
128
+ licenses:
129
+ - ASL-2
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 1.8.10
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: Couchbase ruby driver
152
+ test_files:
153
+ - test/setup.rb
154
+ - test/support/buckets-config.json
155
+ - test/support/sample_design_doc.json
156
+ - test/test_bucket.rb
157
+ - test/test_couchbase.rb
158
+ - test/test_couchdb.rb
159
+ - test/test_document.rb
160
+ - test/test_latch.rb
161
+ - test/test_memcached.rb
162
+ - test/test_rest_client.rb
163
+ - test/test_version.rb
164
+ - test/test_view.rb