mongo_watchable 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +56 -0
- data/Rakefile +25 -0
- data/lib/mongo_watchable/proxy.rb +62 -58
- data/lib/mongo_watchable/watcher.rb +0 -7
- data/test/mongo_watchable_test.rb +229 -0
- data/test/test_helper.rb +1 -0
- metadata +20 -4
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
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
|