ShyCouch 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,13 +3,13 @@ require_relative '../lib/ShyCouch.rb'
3
3
 
4
4
  class TestCouchDBFactory < Test::Unit::TestCase
5
5
  def setup
6
- @valid_settings = $settings
6
+ @valid_settings = $settings
7
7
  end
8
8
 
9
9
  def teardown
10
10
  end
11
11
 
12
12
  def test_create_database
13
- assert_kind_of(ShyCouch::CouchDatabase, ShyCouch.getDB(@valid_settings))
13
+ assert_kind_of(ShyCouch::CouchDatabase, ShyCouch.getDB(@valid_settings))
14
14
  end
15
- end
15
+ end
@@ -3,143 +3,164 @@ require_relative '../lib/ShyCouch.rb'
3
3
 
4
4
  class DesignDocumentTests
5
5
  class ShyCouchDesignTestHelper < ShyCouchTestHelper
6
- def setup
7
- super
8
- # add some docs to the database
9
- @documents = add_some_documents
10
- # make some views
11
- @views = setup_views
12
- # make a design, push it
13
- @design = setup_design_document
14
- @design.push!
15
- end
16
- def teardown
17
- super
18
- end
19
- def setup_views
20
- view1 = ShyCouch::Data::View.new :recipes do
21
- map do
22
- emit(doc.name, null) if doc.kind == "Recipe"
23
- end
24
- end
25
- view2 = ShyCouch::Data::View.new :recipe_count do
26
- map do
27
- emit(doc.name, null) if doc.kind == "Recipe"
28
- end
29
- reduce do
30
- return sum(values)
31
- end
32
- end
33
- return [view1, view2]
34
- end
35
-
36
- def setup_design_document
37
- return ShyCouch::Data::Design.new :food, {:views => @views, :push_to => @couchdb }
38
- end
39
-
40
- def add_some_documents
41
- 4.times do
42
- recipe = Recipe.new(:push_to => @couchdb)
43
- recipe.push!
44
- end
45
- end
6
+ def setup
7
+ super
8
+ # add some docs to the database
9
+ @documents = add_some_documents
10
+ # make some views
11
+ @views = setup_views
12
+ # make a design, push it
13
+ @design = setup_design_document
14
+ @design.push!
15
+ end
16
+ def teardown
17
+ super
18
+ end
19
+ def setup_views
20
+ view1 = ShyCouch::Data::View.new :recipes do
21
+ map do
22
+ emit(doc._id, null) if doc.kind == "Recipe"
23
+ end
24
+ end
25
+ view2 = ShyCouch::Data::View.new :recipe_count do
26
+ map do
27
+ emit(doc.name, null) if doc.kind == "Recipe"
28
+ end
29
+ reduce do
30
+ return sum(values)
31
+ end
32
+ end
33
+ return [view1, view2]
34
+ end
35
+
36
+ def setup_design_document
37
+ return ShyCouch::Data::Design.new :food, {:views => @views, :push_to => @couchdb }
38
+ end
39
+
40
+ def add_some_documents
41
+ 4.times do
42
+ recipe = Recipe.new(:push_to => @couchdb)
43
+ recipe.push!
44
+ end
45
+ end
46
46
  end
47
47
 
48
48
  class TestDesignDocument < ShyCouchDesignTestHelper
49
- Design = ShyCouch::Data::Design
50
- CouchDocument = ShyCouch::Data::CouchDocument
51
-
52
- class Recipe < CouchDocument; end
53
-
54
- def setup
55
- super
56
- end
57
- def teardown
58
- super
59
- end
60
-
61
- def test_create_design
62
- assert_nothing_raised {
63
- @design = setup_design_document
64
- }
65
- end
66
-
67
- def test_create_design_to_db
68
- new_doc = @couchdb.pull_design(@design._id)
69
- assert_equal(@design.as_hash, new_doc.as_hash)
70
- end
49
+ Design = ShyCouch::Data::Design
50
+ CouchDocument = ShyCouch::Data::CouchDocument
51
+
52
+ class Recipe < CouchDocument; end
53
+
54
+ def setup
55
+ super
56
+ end
57
+ def teardown
58
+ super
59
+ end
60
+
61
+ def test_create_design
62
+ assert_nothing_raised {
63
+ @design = setup_design_document
64
+ }
65
+ end
66
+
67
+ def test_kind_key
68
+ assert_equal("Design", @design.kind)
69
+ end
70
+
71
+ def test_create_design_to_db
72
+ new_doc = @couchdb.pull_design(@design._id)
73
+ assert_equal(@design.to_hash, new_doc.to_hash)
74
+ end
75
+
76
+ def test_rev
77
+ assert(@design._rev)
78
+ end
79
+ end
80
+
81
+ class TestDesignDocumentHandleConflicts < ShyCouchDesignTestHelper
82
+ def setup; super; end
83
+
84
+ def test_create_conflicting_design
85
+ assert_nothing_raised ShyCouch::DesignConflict do
86
+ design = ShyCouch::Data::Design.new :food, {:views => @views, :push_to => @couchdb }
87
+ design.push!
88
+ end
89
+ end
90
+
91
+ def teardown; super; end
71
92
  end
72
93
 
73
94
  class TestDesignsInDatabase < ShyCouchDesignTestHelper
74
- def setup
75
- super
76
- end
77
-
78
- def teardown
79
- super
80
- end
81
-
82
- # three different ways of calling the design
83
- def test_get_design_1
84
- result = @couchdb.design(@design.name)
85
- assert_equal(@design, result)
86
- end
87
- def test_get_design_2
88
- result = @couchdb.design(@design)
89
- assert_equal(@design, result)
90
- end
91
- def test_get_design_3
92
- result = @couchdb.design(:food)
93
- assert_equal(@design, result)
94
- end
95
-
96
- def test_modify_design_and_push
97
- @design.views["recipe_count"].delete("map")
98
- @design.push!
99
- end
100
-
95
+ def setup
96
+ super
97
+ end
98
+
99
+ def teardown
100
+ super
101
+ end
102
+
103
+ # three different ways of calling the design
104
+ def test_get_design_1
105
+ result = @couchdb.design(@design.name)
106
+ assert_equal(@design, result)
107
+ end
108
+ def test_get_design_2
109
+ result = @couchdb.design(@design)
110
+ assert_equal(@design, result)
111
+ end
112
+ def test_get_design_3
113
+ result = @couchdb.design(:food)
114
+ assert_equal(@design, result)
115
+ end
116
+
117
+ def test_modify_design_and_push
118
+ @design.views["recipe_count"].delete("map")
119
+ @design.push!
120
+ end
121
+
101
122
  end
102
123
 
103
124
  class TestCallViewFromDesign < ShyCouchDesignTestHelper
104
- def setup
105
- super
106
- end
107
-
108
- def teardown
109
- super
110
- end
111
-
112
- def test_call_view_by_name
113
- # for the map view:
114
- result = @couchdb.design(@design).query_view(:recipes)
115
- # test that we got the right kind of object:
116
- assert_kind_of(ShyCouch::Data::ViewResult, result)
117
- # test that the object has the expected number of rows:
118
- assert_equal(4, result.length)
119
-
120
- # for the reduce view:
121
- result = @couchdb.design(@design).query_view(:recipe_count)
122
- assert_kind_of(ShyCouch::Data::ViewResult, result)
123
- assert_equal(1, result.length)
124
- assert_respond_to(result, :total_rows)
125
- assert_respond_to(result, :offset)
126
- end
127
-
128
- def test_call_view_with_view_object
129
- # for the map view:
130
- result = @couchdb.design(@design).query_view(@views[0])
131
- # test that we got the right kind of object:
132
- assert_kind_of(ShyCouch::Data::ViewResult, result)
133
- # test that the object has the expected number of rows:
134
- assert_equal(4, result.length)
135
- # and that it responds to offset and total rows as method calls:
136
- assert_respond_to(result, :total_rows)
137
- assert_respond_to(result, :offset)
138
-
139
- # for the reduce view:
140
- # TODO
141
- end
142
-
125
+ def setup
126
+ super
127
+ end
128
+
129
+ def teardown
130
+ super
131
+ end
132
+
133
+ def test_call_view_by_name
134
+ # for the map view:
135
+ result = @couchdb.design(@design).query_view(:recipes)
136
+ # test that we got the right kind of object:
137
+ assert_kind_of(ShyCouch::Data::ViewResult, result)
138
+ # test that the object has the expected number of rows:
139
+ assert_equal(4, result.length)
140
+
141
+ # for the reduce view:
142
+ result = @couchdb.design(@design).query_view(:recipe_count)
143
+ assert_kind_of(ShyCouch::Data::ViewResult, result)
144
+ assert_equal(1, result.length)
145
+ assert_respond_to(result, :total_rows)
146
+ assert_respond_to(result, :offset)
147
+ end
148
+
149
+ def test_call_view_with_view_object
150
+ # for the map view:
151
+ result = @couchdb.design(@design).query_view(@views[0])
152
+ # test that we got the right kind of object:
153
+ assert_kind_of(ShyCouch::Data::ViewResult, result)
154
+ # test that the object has the expected number of rows:
155
+ assert_equal(4, result.length)
156
+ # and that it responds to offset and total rows as method calls:
157
+ assert_respond_to(result, :total_rows)
158
+ assert_respond_to(result, :offset)
159
+
160
+ # for the reduce view:
161
+ # TODO
162
+ end
163
+
143
164
  end
144
165
 
145
- end
166
+ end
@@ -0,0 +1,85 @@
1
+ require 'test/unit'
2
+ require_relative '../lib/ShyCouch.rb'
3
+
4
+ class CouchDocumentValidationTests
5
+ class TestDocumentValidation < ShyCouchTestHelper
6
+
7
+ # define a class with some needs
8
+ class FussyRecipe < ShyCouch::Data::CouchDocument
9
+ needs :name
10
+ needs :cost
11
+ end
12
+
13
+ # define a class with some suggests
14
+ class LenientRecipe < ShyCouch::Data::CouchDocument
15
+ suggests :ingredients
16
+ suggests :date
17
+ end
18
+
19
+ # define a class with both needs and suggests
20
+ class PainfulRecipe < ShyCouch::Data::CouchDocument
21
+ needs :name
22
+ needs :cost
23
+ suggests :ingredients
24
+ suggests :date
25
+ end
26
+
27
+ class VariedRecipe < ShyCouch::Data::CouchDocument
28
+ # This just checks that you can pass multiple values
29
+ needs :name, :cost
30
+ suggests :ingredients, :date
31
+ end
32
+
33
+ def setup
34
+ super
35
+ end
36
+
37
+ def test_needs_enforcement
38
+ # Check that docs can be pushed if they satisfy the needs
39
+ fr1 = FussyRecipe.new(:data => {:name => "cool", :cost => 1}, :push_to => @couchdb)
40
+ assert_nothing_raised ShyCouch::DocumentValidationError do
41
+ fr1.push!
42
+ end
43
+
44
+ # Check that it fails if satisfies no needs
45
+ fr2 = FussyRecipe.new(:push_to => @couchdb)
46
+ assert_raises ShyCouch::DocumentValidationError do
47
+ fr2.push!
48
+ end
49
+
50
+ # Check that it fails if it satisfies only some needs
51
+ fr3 = FussyRecipe.new(:data => {:name => "cool"}, :push_to => @couchdb)
52
+ assert_raises ShyCouch::DocumentValidationError do
53
+ fr3.push!
54
+ end
55
+ end
56
+
57
+ def test_suggests_enforcement
58
+ # Check that it fails with no suggestions satisfied
59
+ lr1 = LenientRecipe.new(:push_to => @couchdb)
60
+ assert_raises ShyCouch::DocumentValidationError do
61
+ lr1.push!
62
+ end
63
+
64
+ # Check that it fails with only some suggestions satisfied
65
+ lr2 = LenientRecipe.new(:data => {:ingredients => "not many"}, :push_to => @couchdb)
66
+ end
67
+ def test_suggests_override
68
+ # Check that it succeeds if the suggestions are overriden
69
+ lr1 = LenientRecipe.new(:push_to => @couchdb)
70
+ assert_nothing_raised ShyCouch::DocumentValidationError do
71
+ lr1.push!(:ignore_suggestions => [:ingredients, :date])
72
+ end
73
+
74
+ # Check that it succeeds if some suggestions are satisfied and others are overriden
75
+ lr2 = LenientRecipe.new(:data => {:ingredients => "heaps!"}, :push_to => @couchdb)
76
+ assert_nothing_raised ShyCouch::DocumentValidationError do
77
+ lr2.push!(:ignore_suggestion => :date)
78
+ end
79
+ end
80
+
81
+ def teardown
82
+ super
83
+ end
84
+ end
85
+ end
@@ -3,24 +3,24 @@ require_relative '../lib/ShyCouch.rb'
3
3
 
4
4
  class TestEmailField < Test::Unit::TestCase
5
5
  def setup
6
- @valid_emails = ['bigbeggar@gmail.com', 'helpmeout@bigpond.com'] # more!
7
- @invalid_emails = ['byby.head@heat']#, 'looptheloop@ireallyhopethisisntadomainpleasedontbeadomain.org'] # more!
8
- #commented out the one with an invalid domain cos resolve timeout long
6
+ @valid_emails = ['bigbeggar@gmail.com', 'helpmeout@bigpond.com'] # more!
7
+ @invalid_emails = ['byby.head@heat']#, 'looptheloop@ireallyhopethisisntadomainpleasedontbeadomain.org'] # more!
8
+ #commented out the one with an invalid domain cos resolve timeout long
9
9
  end
10
10
 
11
11
  def teardown; end
12
12
 
13
13
  def test_valid_emails
14
- @valid_emails.each do |email|
15
- email_addr = ShyCouch::Fields::Email_Addr.new(email)
16
- assert_equal(true, email_addr.valid?)
17
- end
14
+ @valid_emails.each do |email|
15
+ email_addr = ShyCouch::Fields::Email_Addr.new(email)
16
+ assert_equal(true, email_addr.valid?)
17
+ end
18
18
  end
19
19
 
20
20
  def test_invalid_emails
21
- @invalid_emails.each do |email|
22
- email_addr = ShyCouch::Fields::Email_Addr.new(email)
23
- assert_equal(false, email_addr.valid?)
24
- end
21
+ @invalid_emails.each do |email|
22
+ email_addr = ShyCouch::Fields::Email_Addr.new(email)
23
+ assert_equal(false, email_addr.valid?)
24
+ end
25
25
  end
26
- end
26
+ end
@@ -2,16 +2,16 @@ require 'test/unit'
2
2
  require_relative '../lib/ShyCouch.rb'
3
3
 
4
4
  class CouchViewTests < Test::Unit::TestCase
5
- JS_MAP_FUNCTION_HEADER = "function ( doc ) { \n "
6
- JS_REDUCE_FUNCTION_HEADER = "function(key, values, rereduce) { \n "
5
+ JS_MAP_FUNCTION_HEADER = "function ( doc ) { \n "
6
+ JS_REDUCE_FUNCTION_HEADER = "function(key, values, rereduce) { \n "
7
7
  JS_FUNCTION_FOOTER = "}"
8
8
  def setup
9
- @couch_views = []
9
+ @couch_views = []
10
10
  end
11
11
 
12
12
  def view(view_name, &block)
13
- #for convenience, and to imitate how it would be used in Camping
14
- @couch_views << ShyCouch::Data::View.new(view_name, &block)
13
+ #for convenience, and to imitate how it would be used in Camping
14
+ @couch_views << ShyCouch::Data::View.new(view_name, &block)
15
15
  end
16
16
  def teardown; end
17
17
 
@@ -19,30 +19,30 @@ class CouchViewTests < Test::Unit::TestCase
19
19
 
20
20
 
21
21
  # def test_define_map_view
22
- # view :five_star_butts do
23
- # map do
24
- # # def function(doc)
25
- # emit(doc) if doc.kind == "butt" and doc.star_rating == 5
26
- # # end
27
- # end
28
- # end
29
- # expected_js = JS_MAP_FUNCTION_HEADER + %{if( doc.kind == 'butt' && doc.star_rating == 5 ) {\n emit(doc)\n}} + JS_FUNCTION_FOOTER
30
- # assert_equal(expected_js, @couch_views[0].map)
22
+ # view :five_star_butts do
23
+ # map do
24
+ # # def function(doc)
25
+ # emit(doc) if doc.kind == "butt" and doc.star_rating == 5
26
+ # # end
27
+ # end
28
+ # end
29
+ # expected_js = JS_MAP_FUNCTION_HEADER + %{if( doc.kind == 'butt' && doc.star_rating == 5 ) {\n emit(doc)\n}} + JS_FUNCTION_FOOTER
30
+ # assert_equal(expected_js, @couch_views[0].map)
31
31
  # end
32
32
  #
33
33
  # def test_define_map_and_reduce_view
34
- # view :beggar_count do
35
- # map do
36
- # emit(doc) if doc.kind == "beggar"
37
- # end
38
- # reduce do
39
- # return sum(values)
40
- # end
41
- # end
42
- # expected_map = JS_MAP_FUNCTION_HEADER + %{if( doc.kind == 'beggar' ) {\n emit(doc)\n}} + JS_FUNCTION_FOOTER
43
- # expected_reduce = JS_REDUCE_FUNCTION_HEADER + %{return sum(values);} + JS_FUNCTION_FOOTER
44
- # assert_equal(expected_map, @couch_views[0].map)
45
- # assert_equal(expected_reduce, @couch_views[0].reduce)
34
+ # view :beggar_count do
35
+ # map do
36
+ # emit(doc) if doc.kind == "beggar"
37
+ # end
38
+ # reduce do
39
+ # return sum(values)
40
+ # end
41
+ # end
42
+ # expected_map = JS_MAP_FUNCTION_HEADER + %{if( doc.kind == 'beggar' ) {\n emit(doc)\n}} + JS_FUNCTION_FOOTER
43
+ # expected_reduce = JS_REDUCE_FUNCTION_HEADER + %{return sum(values);} + JS_FUNCTION_FOOTER
44
+ # assert_equal(expected_map, @couch_views[0].map)
45
+ # assert_equal(expected_reduce, @couch_views[0].reduce)
46
46
  # end
47
47
 
48
48
  end
@@ -51,14 +51,14 @@ class CouchDefaultViewTests < ShyCouchTestHelper
51
51
  # define a class that should have an 'all' method to get all instances of that object
52
52
  class Leg < ShyCouch::Data::CouchDocument; end
53
53
  def setup
54
- super
55
- # add some instances of the object
56
- @test_docs = []
57
- @test_docs << Leg.new(:push_to => @couchdb, :data => {"length"=>30}).push!
58
- @test_docs << Leg.new(:push_to => @couchdb, :data => {"length"=>18, "broken"=>true}).push!
54
+ super
55
+ # add some instances of the object
56
+ @test_docs = []
57
+ @test_docs << Leg.new(:push_to => @couchdb, :data => {"length"=>30}).push!
58
+ @test_docs << Leg.new(:push_to => @couchdb, :data => {"length"=>18, "broken"=>true}).push!
59
59
  end
60
60
  def teardown
61
- super
61
+ super
62
62
  end
63
63
  #
64
64
  # def test_query_all
@@ -67,4 +67,100 @@ class CouchDefaultViewTests < ShyCouchTestHelper
67
67
  # assert_kind_of(ShyCouch::CouchDocumentCollection, @all_legs)
68
68
  # # also test that the doc values worked, and that the response has the docs in it, etc.
69
69
  # end
70
- end
70
+ end
71
+
72
+ class CouchViewTestHelper < ShyCouchTestHelper
73
+ def setup
74
+ super
75
+ # make a view
76
+ view = ShyCouch::Data::View.new :all_recipes do
77
+ map do
78
+ emit(doc._id, doc.length) if doc.kind == "Recipe"
79
+ end
80
+ end
81
+ design = ShyCouch::Data::Design.new :food, {:views => [view], :push_to => @couchdb}
82
+ add_some_documents
83
+ design.push!
84
+ # make a design
85
+ end
86
+ def teardown; super; end
87
+ end
88
+
89
+ class CouchViewResultsTests < CouchViewTestHelper
90
+ def setup
91
+ super
92
+ end
93
+ def test_view_results_is_hash_keyed_by_results
94
+ result = @couchdb.design(:food).query_view(:all_recipes)
95
+ assert_kind_of ShyCouch::Data::ViewResult, result
96
+ # test that it's made of ViewResultRow objects that respond to "id"
97
+ result.each do |k,v|
98
+ assert_kind_of ShyCouch::Data::ViewResult::ViewResultRow, v
99
+ assert_respond_to v, :id
100
+ end
101
+
102
+ end
103
+ def teardown; super; end
104
+ end
105
+
106
+ class CouchViewOptionTests < CouchViewTestHelper
107
+ def setup
108
+ super
109
+ end
110
+
111
+ def test_call_views_with_option
112
+ # just test all the different options and make sure nothing's thrown
113
+ # TODO - change this to test it with all the options, maybe? just to check no errors thrown, etc?
114
+ design = @couchdb.design(:food)
115
+ result = design.query_view(:all_recipes, {:include_docs => true})
116
+ assert_kind_of ShyCouch::Data::CouchDocumentCollection, result
117
+ end
118
+
119
+ def test_all_docs_query_has_docs_as_rows
120
+ # test that if we call a view with "include docs", the iterable of the collection returned is the document itself (as a couch document of the right kind)
121
+ result = @couchdb.design(:food).query_view(:all_recipes, :include_docs => true)
122
+ assert_kind_of ShyCouch::Data::CouchDocumentCollection, result
123
+ #result.each do |row|
124
+ # assert_respond_to row, :kind
125
+ # puts "kind: #{row.kind}"
126
+ #end
127
+ end
128
+
129
+ def test_stringify_options
130
+ # Test that views can be called with string options:
131
+ # key, endkey, startkey
132
+ assert_nothing_raised ShyCouch::ViewError do
133
+ result = @couchdb.design(:food).query_view(:all_recipes, :key => "nice one")
134
+ end
135
+ assert_nothing_raised ShyCouch::ViewError do
136
+ result = @couchdb.design(:food).query_view(:all_recipes, :startkey => "nice one")
137
+ end
138
+ assert_nothing_raised ShyCouch::ViewError do
139
+ result = @couchdb.design(:food).query_view(:all_recipes, :endkey => "nice one")
140
+ end
141
+ end
142
+ def test_handle_empty_response
143
+ assert_nothing_raised NoMethodError do
144
+ # hopefully this key won't exist
145
+ result = @couchdb.design(:food).query_view(:all_recipes, :endkey => "FHDJFHSDJKFNJKNDWKJHjkhkjhjkh^")
146
+ end
147
+ end
148
+
149
+ def test_cannot_send_invalid_option
150
+ assert_raises ShyCouch::ViewError do
151
+ result = @couchdb.design(:food).query_view(:all_recipes, :some_magic => "i want this to be like sql!!")
152
+ end
153
+ end
154
+
155
+ # TODO - individual relevant tests for each option
156
+
157
+ def test_query_by_key
158
+ # querying by key should return a document, not a collection with a single document in it
159
+ recipe = Recipe.new(:push_to => @couchdb, :data => {:length => 10})
160
+ recipe.push!
161
+ doc_from_db = @couchdb.design(:food).query_view(:all_recipes, :key => recipe._id, :include_docs => true)
162
+ assert_kind_of(ShyCouch::Data::CouchDocument, doc_from_db)
163
+ end
164
+
165
+ def teardown; super; end
166
+ end