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 +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
|