samflores-couchrest 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/LICENSE +176 -0
  2. data/README.md +93 -0
  3. data/Rakefile +66 -0
  4. data/THANKS.md +18 -0
  5. data/examples/model/example.rb +144 -0
  6. data/examples/word_count/markov +38 -0
  7. data/examples/word_count/views/books/chunked-map.js +3 -0
  8. data/examples/word_count/views/books/united-map.js +1 -0
  9. data/examples/word_count/views/markov/chain-map.js +6 -0
  10. data/examples/word_count/views/markov/chain-reduce.js +7 -0
  11. data/examples/word_count/views/word_count/count-map.js +6 -0
  12. data/examples/word_count/views/word_count/count-reduce.js +3 -0
  13. data/examples/word_count/word_count.rb +46 -0
  14. data/examples/word_count/word_count_query.rb +40 -0
  15. data/examples/word_count/word_count_views.rb +26 -0
  16. data/lib/couchrest/commands/generate.rb +71 -0
  17. data/lib/couchrest/commands/push.rb +103 -0
  18. data/lib/couchrest/core/database.rb +316 -0
  19. data/lib/couchrest/core/design.rb +89 -0
  20. data/lib/couchrest/core/document.rb +96 -0
  21. data/lib/couchrest/core/response.rb +16 -0
  22. data/lib/couchrest/core/server.rb +88 -0
  23. data/lib/couchrest/core/view.rb +4 -0
  24. data/lib/couchrest/helper/pager.rb +103 -0
  25. data/lib/couchrest/helper/streamer.rb +44 -0
  26. data/lib/couchrest/mixins/attachments.rb +31 -0
  27. data/lib/couchrest/mixins/callbacks.rb +483 -0
  28. data/lib/couchrest/mixins/design_doc.rb +64 -0
  29. data/lib/couchrest/mixins/document_queries.rb +48 -0
  30. data/lib/couchrest/mixins/extended_attachments.rb +68 -0
  31. data/lib/couchrest/mixins/extended_document_mixins.rb +6 -0
  32. data/lib/couchrest/mixins/properties.rb +125 -0
  33. data/lib/couchrest/mixins/validation.rb +234 -0
  34. data/lib/couchrest/mixins/views.rb +168 -0
  35. data/lib/couchrest/mixins.rb +4 -0
  36. data/lib/couchrest/monkeypatches.rb +119 -0
  37. data/lib/couchrest/more/casted_model.rb +28 -0
  38. data/lib/couchrest/more/extended_document.rb +217 -0
  39. data/lib/couchrest/more/property.rb +40 -0
  40. data/lib/couchrest/support/blank.rb +42 -0
  41. data/lib/couchrest/support/class.rb +191 -0
  42. data/lib/couchrest/validation/auto_validate.rb +163 -0
  43. data/lib/couchrest/validation/contextual_validators.rb +78 -0
  44. data/lib/couchrest/validation/validation_errors.rb +118 -0
  45. data/lib/couchrest/validation/validators/absent_field_validator.rb +74 -0
  46. data/lib/couchrest/validation/validators/confirmation_validator.rb +99 -0
  47. data/lib/couchrest/validation/validators/format_validator.rb +117 -0
  48. data/lib/couchrest/validation/validators/formats/email.rb +66 -0
  49. data/lib/couchrest/validation/validators/formats/url.rb +43 -0
  50. data/lib/couchrest/validation/validators/generic_validator.rb +120 -0
  51. data/lib/couchrest/validation/validators/length_validator.rb +134 -0
  52. data/lib/couchrest/validation/validators/method_validator.rb +89 -0
  53. data/lib/couchrest/validation/validators/numeric_validator.rb +104 -0
  54. data/lib/couchrest/validation/validators/required_field_validator.rb +109 -0
  55. data/lib/couchrest.rb +189 -0
  56. data/spec/couchrest/core/couchrest_spec.rb +201 -0
  57. data/spec/couchrest/core/database_spec.rb +745 -0
  58. data/spec/couchrest/core/design_spec.rb +131 -0
  59. data/spec/couchrest/core/document_spec.rb +311 -0
  60. data/spec/couchrest/core/server_spec.rb +35 -0
  61. data/spec/couchrest/helpers/pager_spec.rb +122 -0
  62. data/spec/couchrest/helpers/streamer_spec.rb +23 -0
  63. data/spec/couchrest/more/casted_extended_doc_spec.rb +40 -0
  64. data/spec/couchrest/more/casted_model_spec.rb +98 -0
  65. data/spec/couchrest/more/extended_doc_attachment_spec.rb +130 -0
  66. data/spec/couchrest/more/extended_doc_spec.rb +509 -0
  67. data/spec/couchrest/more/extended_doc_view_spec.rb +207 -0
  68. data/spec/couchrest/more/property_spec.rb +130 -0
  69. data/spec/couchrest/support/class_spec.rb +59 -0
  70. data/spec/fixtures/attachments/README +3 -0
  71. data/spec/fixtures/attachments/couchdb.png +0 -0
  72. data/spec/fixtures/attachments/test.html +11 -0
  73. data/spec/fixtures/more/article.rb +34 -0
  74. data/spec/fixtures/more/card.rb +20 -0
  75. data/spec/fixtures/more/course.rb +14 -0
  76. data/spec/fixtures/more/event.rb +6 -0
  77. data/spec/fixtures/more/invoice.rb +17 -0
  78. data/spec/fixtures/more/person.rb +8 -0
  79. data/spec/fixtures/more/question.rb +6 -0
  80. data/spec/fixtures/more/service.rb +12 -0
  81. data/spec/fixtures/views/lib.js +3 -0
  82. data/spec/fixtures/views/test_view/lib.js +3 -0
  83. data/spec/fixtures/views/test_view/only-map.js +4 -0
  84. data/spec/fixtures/views/test_view/test-map.js +3 -0
  85. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  86. data/spec/spec.opts +6 -0
  87. data/spec/spec_helper.rb +26 -0
  88. data/utils/remap.rb +27 -0
  89. data/utils/subset.rb +30 -0
  90. metadata +219 -0
@@ -0,0 +1,98 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+ require File.join(FIXTURE_PATH, 'more', 'card')
3
+
4
+ class WithCastedModelMixin < Hash
5
+ include CouchRest::CastedModel
6
+ property :name
7
+ end
8
+
9
+ class DummyModel < CouchRest::ExtendedDocument
10
+ use_database TEST_SERVER.default_database
11
+ raise "Default DB not set" if TEST_SERVER.default_database.nil?
12
+ property :casted_attribute, :cast_as => 'WithCastedModelMixin'
13
+ property :keywords, :cast_as => ["String"]
14
+ end
15
+
16
+ describe CouchRest::CastedModel do
17
+
18
+ describe "A non hash class including CastedModel" do
19
+ it "should fail raising and include error" do
20
+ lambda do
21
+ class NotAHashButWithCastedModelMixin
22
+ include CouchRest::CastedModel
23
+ property :name
24
+ end
25
+
26
+ end.should raise_error
27
+ end
28
+ end
29
+
30
+ describe "isolated" do
31
+ before(:each) do
32
+ @obj = WithCastedModelMixin.new
33
+ end
34
+ it "should automatically include the property mixin and define getters and setters" do
35
+ @obj.name = 'Matt'
36
+ @obj.name.should == 'Matt'
37
+ end
38
+ end
39
+
40
+ describe "casted as attribute" do
41
+ before(:each) do
42
+ @obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
43
+ @casted_obj = @obj.casted_attribute
44
+ end
45
+
46
+ it "should be available from its parent" do
47
+ @casted_obj.should be_an_instance_of(WithCastedModelMixin)
48
+ end
49
+
50
+ it "should have the getters defined" do
51
+ @casted_obj.name.should == 'whatever'
52
+ end
53
+
54
+ it "should know who casted it" do
55
+ @casted_obj.casted_by.should == @obj
56
+ end
57
+ end
58
+
59
+ describe "casted as an array of a different type" do
60
+ before(:each) do
61
+ @obj = DummyModel.new(:keywords => ['couch', 'sofa', 'relax', 'canapé'])
62
+ end
63
+
64
+ it "should cast the array propery" do
65
+ @obj.keywords.should be_an_instance_of(Array)
66
+ @obj.keywords.first.should == 'couch'
67
+ end
68
+
69
+ end
70
+
71
+ describe "saved document with casted models" do
72
+ before(:each) do
73
+ reset_test_db!
74
+ @obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
75
+ @obj.save.should be_true
76
+ @obj = DummyModel.get(@obj.id)
77
+ end
78
+
79
+ it "should be able to load with the casted models" do
80
+ casted_obj = @obj.casted_attribute
81
+ casted_obj.should_not be_nil
82
+ casted_obj.should be_an_instance_of(WithCastedModelMixin)
83
+ end
84
+
85
+ it "should have defined getters for the casted model" do
86
+ casted_obj = @obj.casted_attribute
87
+ casted_obj.name.should == "whatever"
88
+ end
89
+
90
+ it "should have defined setters for the casted model" do
91
+ casted_obj = @obj.casted_attribute
92
+ casted_obj.name = "test"
93
+ casted_obj.name.should == "test"
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,130 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "ExtendedDocument attachments" do
4
+
5
+ describe "#has_attachment?" do
6
+ before(:each) do
7
+ reset_test_db!
8
+ @obj = Basic.new
9
+ @obj.save.should == true
10
+ @file = File.open(FIXTURE_PATH + '/attachments/test.html')
11
+ @attachment_name = 'my_attachment'
12
+ @obj.create_attachment(:file => @file, :name => @attachment_name)
13
+ end
14
+
15
+ it 'should return false if there is no attachment' do
16
+ @obj.has_attachment?('bogus').should be_false
17
+ end
18
+
19
+ it 'should return true if there is an attachment' do
20
+ @obj.has_attachment?(@attachment_name).should be_true
21
+ end
22
+
23
+ it 'should return true if an object with an attachment is reloaded' do
24
+ @obj.save.should be_true
25
+ reloaded_obj = Basic.get(@obj.id)
26
+ reloaded_obj.has_attachment?(@attachment_name).should be_true
27
+ end
28
+
29
+ it 'should return false if an attachment has been removed' do
30
+ @obj.delete_attachment(@attachment_name)
31
+ @obj.has_attachment?(@attachment_name).should be_false
32
+ end
33
+ end
34
+
35
+ describe "creating an attachment" do
36
+ before(:each) do
37
+ @obj = Basic.new
38
+ @obj.save.should == true
39
+ @file_ext = File.open(FIXTURE_PATH + '/attachments/test.html')
40
+ @file_no_ext = File.open(FIXTURE_PATH + '/attachments/README')
41
+ @attachment_name = 'my_attachment'
42
+ @content_type = 'media/mp3'
43
+ end
44
+
45
+ it "should create an attachment from file with an extension" do
46
+ @obj.create_attachment(:file => @file_ext, :name => @attachment_name)
47
+ @obj.save.should == true
48
+ reloaded_obj = Basic.get(@obj.id)
49
+ reloaded_obj['_attachments'][@attachment_name].should_not be_nil
50
+ end
51
+
52
+ it "should create an attachment from file without an extension" do
53
+ @obj.create_attachment(:file => @file_no_ext, :name => @attachment_name)
54
+ @obj.save.should == true
55
+ reloaded_obj = Basic.get(@obj.id)
56
+ reloaded_obj['_attachments'][@attachment_name].should_not be_nil
57
+ end
58
+
59
+ it 'should raise ArgumentError if :file is missing' do
60
+ lambda{ @obj.create_attachment(:name => @attachment_name) }.should raise_error
61
+ end
62
+
63
+ it 'should raise ArgumentError if :name is missing' do
64
+ lambda{ @obj.create_attachment(:file => @file_ext) }.should raise_error
65
+ end
66
+
67
+ it 'should set the content-type if passed' do
68
+ @obj.create_attachment(:file => @file_ext, :name => @attachment_name, :content_type => @content_type)
69
+ @obj['_attachments'][@attachment_name]['content-type'].should == @content_type
70
+ end
71
+ end
72
+
73
+ describe 'reading, updating, and deleting an attachment' do
74
+ before(:each) do
75
+ @obj = Basic.new
76
+ @file = File.open(FIXTURE_PATH + '/attachments/test.html')
77
+ @attachment_name = 'my_attachment'
78
+ @obj.create_attachment(:file => @file, :name => @attachment_name)
79
+ @obj.save.should == true
80
+ @file.rewind
81
+ @content_type = 'media/mp3'
82
+ end
83
+
84
+ it 'should read an attachment that exists' do
85
+ @obj.read_attachment(@attachment_name).should == @file.read
86
+ end
87
+
88
+ it 'should update an attachment that exists' do
89
+ file = File.open(FIXTURE_PATH + '/attachments/README')
90
+ @file.should_not == file
91
+ @obj.update_attachment(:file => file, :name => @attachment_name)
92
+ @obj.save
93
+ reloaded_obj = Basic.get(@obj.id)
94
+ file.rewind
95
+ reloaded_obj.read_attachment(@attachment_name).should_not == @file.read
96
+ reloaded_obj.read_attachment(@attachment_name).should == file.read
97
+ end
98
+
99
+ it 'should se the content-type if passed' do
100
+ file = File.open(FIXTURE_PATH + '/attachments/README')
101
+ @file.should_not == file
102
+ @obj.update_attachment(:file => file, :name => @attachment_name, :content_type => @content_type)
103
+ @obj['_attachments'][@attachment_name]['content-type'].should == @content_type
104
+ end
105
+
106
+ it 'should delete an attachment that exists' do
107
+ @obj.delete_attachment(@attachment_name)
108
+ @obj.save
109
+ lambda{Basic.get(@obj.id).read_attachment(@attachment_name)}.should raise_error
110
+ end
111
+ end
112
+
113
+ describe "#attachment_url" do
114
+ before(:each) do
115
+ @obj = Basic.new
116
+ @file = File.open(FIXTURE_PATH + '/attachments/test.html')
117
+ @attachment_name = 'my_attachment'
118
+ @obj.create_attachment(:file => @file, :name => @attachment_name)
119
+ @obj.save.should == true
120
+ end
121
+
122
+ it 'should return nil if attachment does not exist' do
123
+ @obj.attachment_url('bogus').should be_nil
124
+ end
125
+
126
+ it 'should return the attachment URL as specified by CouchDB HttpDocumentApi' do
127
+ @obj.attachment_url(@attachment_name).should == "#{Basic.database}/#{@obj.id}/#{@attachment_name}"
128
+ end
129
+ end
130
+ end