mongo_watchable 0.1.0 → 0.1.1

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.
data/README.markdown ADDED
@@ -0,0 +1,56 @@
1
+ MongoWatchable
2
+ ==============
3
+
4
+ A simple many-to-many assocation between watchers and watchables for mongodb.
5
+
6
+ Requirements
7
+ ------------
8
+
9
+ - MongoDB
10
+ - MongoMapper
11
+
12
+ Installation
13
+ ------------
14
+
15
+ sudo gem install mongo_watchable
16
+
17
+ Simple Example
18
+ --------------
19
+
20
+ class User
21
+ include MongoMapper::Document
22
+ include MongoWatchable::Watcher
23
+ end
24
+
25
+ class Widget
26
+ include MongoMapper::Document
27
+ include MongoWatchable::Watchable
28
+ end
29
+
30
+ To watch it:
31
+
32
+ user.watch(widget)
33
+
34
+ Check if user is watching a widget:
35
+
36
+ user.watching?(widget)
37
+
38
+ Return count of all widgets a user is watching:
39
+
40
+ user.widget_watchings.count
41
+
42
+ Return all widgets a user is watching:
43
+
44
+ user.widget_watchings
45
+
46
+ Return all users watching widget:
47
+
48
+ widget.user_watchers
49
+
50
+ Return count of all users watching widget:
51
+
52
+ widget.user_watchers.count
53
+
54
+ Unwatch a widget
55
+
56
+ user.unwatch(widget)
data/Rakefile CHANGED
@@ -1,3 +1,10 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
1
8
  begin
2
9
  GEM = "mongo_watchable"
3
10
  AUTHOR = "Jonathan Bell"
@@ -26,9 +33,27 @@ begin
26
33
  # Development dependencies. Not installed by default.
27
34
  # Install with: sudo gem install formtastic --development
28
35
  #s.add_development_dependency 'rspec-rails', '>= 1.2.6'
36
+ s.add_development_dependency 'shoulda', '>= 2.10.0'
29
37
  end
30
38
 
31
39
  Jeweler::GemcutterTasks.new
32
40
  rescue LoadError
33
41
  puts "[mongo_watchable:] Jeweler - or one of its dependencies - is not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
42
+ end
43
+
44
+ desc 'Test the mongo_watchable plugin.'
45
+ Rake::TestTask.new(:test) do |t|
46
+ t.libs << 'lib'
47
+ t.libs << 'test'
48
+ t.pattern = 'test/**/*_test.rb'
49
+ t.verbose = true
50
+ end
51
+
52
+ desc 'Generate documentation for the mongo_watchable plugin.'
53
+ Rake::RDocTask.new(:rdoc) do |rdoc|
54
+ rdoc.rdoc_dir = 'rdoc'
55
+ rdoc.title = 'Mongo Watchable'
56
+ rdoc.options << '--line-numbers' << '--inline-source'
57
+ rdoc.rdoc_files.include('README')
58
+ rdoc.rdoc_files.include('lib/**/*.rb')
34
59
  end
@@ -1,63 +1,67 @@
1
1
  module MongoWatchable
2
2
  class Proxy
3
- attr_reader :array_key
4
- attr_reader :model
5
- attr_reader :target_class
6
-
7
- def initialize(model, array_key, target_class)
8
- @model, @array_key, @target_class = model, array_key, target_class
9
- end
10
-
11
- def to_a
12
- fetch_all.to_a
13
- end
14
-
15
- def count
16
- array.size
17
- end
18
-
19
- def all(opts = {})
20
- fetch_all
21
- end
22
-
23
- def each(&block)
24
- fetch_all.each {|entry| yield entry}
25
- end
26
-
27
- def find(id)
28
- return nil unless array.include?(id)
29
- target_class.find(id)
30
- end
31
-
32
- def first(opts = {})
33
- return @first ||= target_class.find(array.first) if opts.empty?
34
- target_class.first(opts.merge(:_id.in => array))
35
- end
36
-
37
- def last(opts = {})
38
- return @last ||= target_class.find(array.last) if opts.empty?
39
- target_class.last(opts.merge(:_id.in => array))
40
- end
41
-
42
- alias :size :count
43
-
44
- def << (entry)
45
- array << entry.id
46
- @fetch ? @fetch << entry : fetch_all
47
- end
48
-
49
- def delete(entry)
50
- array.delete entry.id
51
- @fetch ? @fetch.delete(entry) : fetch_all
52
- end
53
-
54
- def inspect
55
- all.inspect
56
- end
57
-
58
- private
59
- def fetch_all
60
- @fetch ||= target_class.find(array)
3
+ attr_reader :array_key
4
+ attr_reader :model
5
+ attr_reader :target_class
6
+
7
+ def initialize(model, array_key, target_class)
8
+ @model, @array_key, @target_class = model, array_key, target_class
9
+ end
10
+
11
+ def to_a
12
+ fetch_all.to_a
13
+ end
14
+
15
+ def count
16
+ array.size
17
+ end
18
+
19
+ def all(opts = {})
20
+ fetch_all
21
+ end
22
+
23
+ def each(&block)
24
+ fetch_all.each {|entry| yield entry}
25
+ end
26
+
27
+ def find(id)
28
+ return nil unless array.include?(id)
29
+ target_class.find(id)
30
+ end
31
+
32
+ def first(opts = {})
33
+ return @first ||= target_class.find(array.first) if opts.empty?
34
+ target_class.first(opts.merge(:_id.in => array))
35
+ end
36
+
37
+ def last(opts = {})
38
+ return @last ||= target_class.find(array.last) if opts.empty?
39
+ target_class.last(opts.merge(:_id.in => array))
40
+ end
41
+
42
+ def empty?
43
+ array.empty?
44
+ end
45
+
46
+ alias :size :count
47
+
48
+ def << (entry)
49
+ array << entry.id
50
+ @fetch ? @fetch << entry : fetch_all
51
+ end
52
+
53
+ def delete(entry)
54
+ array.delete entry.id
55
+ @fetch ? @fetch.delete(entry) : fetch_all
56
+ end
57
+
58
+ def inspect
59
+ all.inspect
60
+ end
61
+
62
+ private
63
+ def fetch_all
64
+ @fetch ||= target_class.find(array)
61
65
  end
62
66
 
63
67
  def array
@@ -77,13 +77,6 @@ module MongoWatchable
77
77
  end
78
78
 
79
79
  private
80
-
81
- def watch(watchable)
82
- klass = watchable
83
- while klass.superclass && klass.superclass.include?(MongoWatchable::Watchable)
84
- klass = klass.superclass
85
- end
86
- end
87
80
  def root_watching_class(instance)
88
81
  klass = instance
89
82
  while klass.superclass && klass.superclass.include?(MongoWatchable::Watchable)
@@ -0,0 +1,229 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class MongoWatchableTest < ActiveSupport::TestCase
4
+
5
+ context "user unwatches non-watching widget with unwatch" do
6
+ setup do
7
+ @user = User.create!(:name => 'foo')
8
+ @widget = Widget.create!(:name => 'bar')
9
+
10
+ @return = @user.unwatch(@widget)
11
+ end
12
+
13
+ should "return with false" do
14
+ assert !@return
15
+ end
16
+ end
17
+
18
+ context "user unwatches non-watching widget with unwatch!" do
19
+ setup do
20
+ @user = User.create!(:name => 'foo')
21
+ @widget = Widget.create!(:name => 'bar')
22
+ end
23
+
24
+ should "throw standard error" do
25
+ assert_raises RuntimeError do
26
+ @user.unwatch!(@widget)
27
+ end
28
+ end
29
+ end
30
+
31
+ context "user watching widget with watch" do
32
+ setup do
33
+ @user = User.create!(:name => 'foo')
34
+ @widget = Widget.create!(:name => 'bar')
35
+
36
+ @return = @user.watch(@widget)
37
+ @user.reload
38
+ @widget.reload
39
+ end
40
+
41
+ should "should only have 1 widget in widget_watchings array" do
42
+ assert_equal 1, @user.widget_watchings.size
43
+ end
44
+
45
+ should "should have widget in widget watchings array" do
46
+ assert_equal @widget, @user.widget_watchings.first
47
+ end
48
+
49
+ should "have only one watcher in widgets user_watchers array" do
50
+ assert_equal 1, @widget.user_watchers.size
51
+ end
52
+
53
+ should "be the watcher in widgets user_watchers array" do
54
+ assert_equal @user, @widget.user_watchers.first
55
+ end
56
+
57
+ should "return true for watching?" do
58
+ assert @user.watching?(@widget)
59
+ end
60
+
61
+ should "return with true" do
62
+ assert @return
63
+ end
64
+
65
+ context "and then watches widget again" do
66
+ setup do
67
+ @return = @user.watch(@widget)
68
+ end
69
+
70
+ should "return with false" do
71
+ assert !@return
72
+ end
73
+ end
74
+
75
+ context "and another widget" do
76
+ setup do
77
+ @widget2 = Widget.create!(:name => 'baz')
78
+ @return = @user.watch(@widget2)
79
+ @user.reload
80
+ @widget2.reload
81
+ end
82
+
83
+ should "return with true" do
84
+ assert @return
85
+ end
86
+
87
+ should "should only have 2 widgets in widget_watchings array" do
88
+ assert_equal 2, @user.widget_watchings.size
89
+ end
90
+
91
+ should "should have widget in widget watchings array" do
92
+ assert_equal @widget, @user.widget_watchings.first
93
+ end
94
+
95
+ should "should have widget2 in widget watchings array" do
96
+ assert_equal @widget2, @user.widget_watchings.last
97
+ end
98
+
99
+ should "have only one watcher in widget's user_watchers array" do
100
+ assert_equal 1, @widget.user_watchers.size
101
+ end
102
+
103
+ should "be the watcher in widget's user_watchers array" do
104
+ assert_equal @user, @widget.user_watchers.first
105
+ end
106
+
107
+ should "have only one watcher in widget2's user_watchers array" do
108
+ assert_equal 1, @widget2.user_watchers.size
109
+ end
110
+
111
+ should "be the watcher in widget2's user_watchers array" do
112
+ assert_equal @user, @widget2.user_watchers.first
113
+ end
114
+ end
115
+
116
+ context "and then unwatched with unwatch" do
117
+ setup do
118
+ @return = @user.unwatch(@widget)
119
+ @user.reload
120
+ @widget.reload
121
+ end
122
+
123
+ should "have no widgets in widget_watchings array" do
124
+ assert @user.widget_watchings.empty?
125
+ end
126
+
127
+ should "have no user_watchers in widget" do
128
+ assert @widget.user_watchers.empty?
129
+ end
130
+
131
+ should "return with true" do
132
+ assert @return
133
+ end
134
+ end
135
+ end
136
+
137
+ context "user watching widget with watch!" do
138
+ setup do
139
+ @user = User.create!(:name => 'foo')
140
+ @widget = Widget.create!(:name => 'bar')
141
+
142
+ @user.watch!(@widget)
143
+ @user.reload
144
+ @widget.reload
145
+ end
146
+
147
+ should "should only have 1 widget in widget_watchings array" do
148
+ assert_equal 1, @user.widget_watchings.size
149
+ end
150
+
151
+ should "should have widget in widget watchings array" do
152
+ assert_equal @widget, @user.widget_watchings.first
153
+ end
154
+
155
+ should "have only one watcher in widgets user_watchers array" do
156
+ assert_equal 1, @widget.user_watchers.size
157
+ end
158
+
159
+ should "be the watcher in widgets user_watchers array" do
160
+ assert_equal @user, @widget.user_watchers.first
161
+ end
162
+
163
+ should "return true for watching?" do
164
+ assert @user.watching?(@widget)
165
+ end
166
+
167
+ context "and another widget" do
168
+ setup do
169
+ @widget2 = Widget.create!(:name => 'baz')
170
+ @user.watch!(@widget2)
171
+ @user.reload
172
+ @widget2.reload
173
+ end
174
+
175
+ should "should only have 2 widgets in widget_watchings array" do
176
+ assert_equal 2, @user.widget_watchings.size
177
+ end
178
+
179
+ should "should have widget in widget watchings array" do
180
+ assert_equal @widget, @user.widget_watchings.first
181
+ end
182
+
183
+ should "should have widget2 in widget watchings array" do
184
+ assert_equal @widget2, @user.widget_watchings.last
185
+ end
186
+
187
+ should "have only one watcher in widget's user_watchers array" do
188
+ assert_equal 1, @widget.user_watchers.size
189
+ end
190
+
191
+ should "be the watcher in widget's user_watchers array" do
192
+ assert_equal @user, @widget.user_watchers.first
193
+ end
194
+
195
+ should "have only one watcher in widget2's user_watchers array" do
196
+ assert_equal 1, @widget2.user_watchers.size
197
+ end
198
+
199
+ should "be the watcher in widget2's user_watchers array" do
200
+ assert_equal @user, @widget2.user_watchers.first
201
+ end
202
+ end
203
+
204
+ context "and then watches widget again" do
205
+ should "raise RuntimeError" do
206
+ assert_raises RuntimeError do
207
+ @user.watch!(@widget)
208
+ end
209
+ end
210
+ end
211
+
212
+ context "and then unwatched with unwatch!" do
213
+ setup do
214
+ @user.unwatch!(@widget)
215
+ @user.reload
216
+ @widget.reload
217
+ end
218
+
219
+ should "have no widgets in widget_watchings array" do
220
+ assert @user.widget_watchings.empty?
221
+ end
222
+
223
+ should "have no user_watchers in widget" do
224
+ assert @widget.user_watchers.empty?
225
+ end
226
+ end
227
+ end
228
+
229
+ end
data/test/test_helper.rb CHANGED
@@ -3,6 +3,7 @@ require 'active_support'
3
3
 
4
4
  require 'active_support/test_case'
5
5
  require 'test/unit'
6
+ require 'shoulda'
6
7
 
7
8
  ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
8
9
  env_rb = File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jonathan Bell
@@ -31,14 +31,28 @@ dependencies:
31
31
  version: 0.7.0
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: shoulda
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 2
43
+ - 10
44
+ - 0
45
+ version: 2.10.0
46
+ type: :development
47
+ version_requirements: *id002
34
48
  description: A ruby gem for adding watching to mongo documents.
35
49
  email: jonbell@spamcop.net
36
50
  executables: []
37
51
 
38
52
  extensions: []
39
53
 
40
- extra_rdoc_files: []
41
-
54
+ extra_rdoc_files:
55
+ - README.markdown
42
56
  files:
43
57
  - MIT-LICENSE
44
58
  - Rakefile
@@ -46,6 +60,7 @@ files:
46
60
  - lib/mongo_watchable/proxy.rb
47
61
  - lib/mongo_watchable/watchable.rb
48
62
  - lib/mongo_watchable/watcher.rb
63
+ - README.markdown
49
64
  has_rdoc: true
50
65
  homepage: http://github.com/jonbell/mongo_watchable
51
66
  licenses: []
@@ -77,4 +92,5 @@ signing_key:
77
92
  specification_version: 3
78
93
  summary: A ruby gem for adding watching to mongo documents.
79
94
  test_files:
95
+ - test/mongo_watchable_test.rb
80
96
  - test/test_helper.rb