mongoid-doable 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +20 -0
- data/README.md +65 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/lib/mongoid-doable.rb +3 -0
- data/lib/mongoid/doable.rb +163 -0
- data/spec/mongoid/doable_spec.rb +254 -0
- data/spec/spec_helper.rb +35 -0
- metadata +170 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 aproxacs
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# mongoid-doable
|
2
|
+
|
3
|
+
While I was working with rails and mongoid, the functions like below was necessary.
|
4
|
+
|
5
|
+
user.like(comment)
|
6
|
+
user.bookmark(course)
|
7
|
+
user.register(course)
|
8
|
+
user.follow(another_user)
|
9
|
+
|
10
|
+
While implementing these functions, I found that they all do the same thing in the model, they just have a different expression. So the mongoid-doable came out.
|
11
|
+
|
12
|
+
|
13
|
+
# Installation
|
14
|
+
#### Using Gem
|
15
|
+
|
16
|
+
gem install mongoid-doable
|
17
|
+
|
18
|
+
#### Using bundler
|
19
|
+
|
20
|
+
gem 'mongoid-doable'
|
21
|
+
|
22
|
+
|
23
|
+
# Examples
|
24
|
+
|
25
|
+
class Course
|
26
|
+
include Monogid::Document
|
27
|
+
include Monogid::Doable
|
28
|
+
doable :like, by: :user
|
29
|
+
end
|
30
|
+
class User
|
31
|
+
include Monogid::Document
|
32
|
+
include Monogid::Doable
|
33
|
+
doer :like, :course
|
34
|
+
end
|
35
|
+
|
36
|
+
user = User.create
|
37
|
+
course = Course.create
|
38
|
+
|
39
|
+
user.like!(course) # or
|
40
|
+
user.like_course!(course) # or
|
41
|
+
course.liked_by!(user) # or
|
42
|
+
|
43
|
+
user.liking_courses
|
44
|
+
user.liking_courses_count
|
45
|
+
|
46
|
+
course.likers
|
47
|
+
course.likers_count
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
# Contributing to mongoid-doable
|
52
|
+
|
53
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
54
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
55
|
+
* Fork the project.
|
56
|
+
* Start a feature/bugfix branch.
|
57
|
+
* Commit and push until you are happy with your contribution.
|
58
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
59
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
60
|
+
|
61
|
+
== Copyright
|
62
|
+
|
63
|
+
Copyright (c) 2013 aproxacs. See LICENSE.txt for
|
64
|
+
further details.
|
65
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "mongoid-doable"
|
18
|
+
gem.homepage = "http://github.com/aproxacs/mongoid-doable"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %q{Able to do something like 'bookmark', 'like' or 'follow' with mongoid}
|
21
|
+
gem.description = %q{Able to do something like 'bookmark', 'like' or 'follow' with mongoid}
|
22
|
+
gem.email = "aproxacs@gmail.com"
|
23
|
+
gem.authors = ["aproxacs"]
|
24
|
+
gem.files = [
|
25
|
+
"Rakefile",
|
26
|
+
"README.md",
|
27
|
+
"VERSION",
|
28
|
+
"lib/mongoid-doable.rb",
|
29
|
+
"lib/mongoid/*.rb",
|
30
|
+
"spec/**/*.rb"
|
31
|
+
]
|
32
|
+
|
33
|
+
# dependencies defined in Gemfile
|
34
|
+
end
|
35
|
+
Jeweler::RubygemsDotOrgTasks.new
|
36
|
+
|
37
|
+
require 'rspec/core'
|
38
|
+
require 'rspec/core/rake_task'
|
39
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
40
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
41
|
+
end
|
42
|
+
|
43
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
44
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
45
|
+
spec.rcov = true
|
46
|
+
end
|
47
|
+
|
48
|
+
task :default => :spec
|
49
|
+
|
50
|
+
require 'rdoc/task'
|
51
|
+
Rake::RDocTask.new do |rdoc|
|
52
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
53
|
+
|
54
|
+
rdoc.rdoc_dir = 'rdoc'
|
55
|
+
rdoc.title = "mongoid-doable #{version}"
|
56
|
+
rdoc.rdoc_files.include('README*')
|
57
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
58
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Doable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do |base|
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# Examples
|
10
|
+
# class Course
|
11
|
+
# include Monogid::Document
|
12
|
+
# include Monogid::Doable
|
13
|
+
#
|
14
|
+
# doable :like, by: :user
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# class User
|
18
|
+
# include Monogid::Document
|
19
|
+
# include Monogid::Doable
|
20
|
+
#
|
21
|
+
# doer :like, :course
|
22
|
+
#
|
23
|
+
# doable :follow, by: :user
|
24
|
+
# doer :follow, :user
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# user = User.first
|
28
|
+
# course = Course.first
|
29
|
+
#
|
30
|
+
# user.like!(course) # or
|
31
|
+
# user.like_course!(course) # or
|
32
|
+
# course.liked_by!(user) # or
|
33
|
+
#
|
34
|
+
# user.liking_courses
|
35
|
+
# user.liking_courses_count
|
36
|
+
#
|
37
|
+
# course.likers
|
38
|
+
# course.likers_count
|
39
|
+
#
|
40
|
+
|
41
|
+
def doable(action, options = {})
|
42
|
+
doer_models[action.to_sym] = (options[:by] || :user).to_s.classify.constantize
|
43
|
+
|
44
|
+
action = action.to_s # "like"
|
45
|
+
base_action = (action[-1] == "e" ? action.chop : action) # "lik"
|
46
|
+
passive_action = base_action + "ed" # "liked"
|
47
|
+
doer_action = base_action + "ers" # "likers"
|
48
|
+
|
49
|
+
field_name = "#{doer_action}_ids" # "likers_ids"
|
50
|
+
counter_field_name = "#{doer_action}_count" # "likers_count"
|
51
|
+
field field_name, type: Array, default: [], versioned: false # field :likers_ids, type: Array, default: [], versioned: false
|
52
|
+
field counter_field_name, type: Integer, default: 0, versioned: false # field :likers_count, type: Integer, default: 0, versioned: false
|
53
|
+
|
54
|
+
define_method "#{doer_action}" do # def likers
|
55
|
+
klass = self.class.doer_models[action.to_sym] # klass = User
|
56
|
+
klass.where(:"_id".in => send(field_name)) # klass.where(:likers_ids.in => likers_ids)
|
57
|
+
end # end
|
58
|
+
|
59
|
+
define_method "#{passive_action}_by?" do |actor| # def liked_by?(actor)
|
60
|
+
return false if actor.blank? # return false if actor.blank?
|
61
|
+
send(field_name).include? actor.id # likers_ids.include? actor.id
|
62
|
+
end # end
|
63
|
+
|
64
|
+
define_method "#{passive_action}_by!" do |actor| # def liked_by!(actor)
|
65
|
+
return false if actor.blank? # return false if actor.blank?
|
66
|
+
if actor.respond_to?("#{action}!") # if actor.respond_to?(:like!)
|
67
|
+
actor.send("#{action}!", self) # actor.like!(self)
|
68
|
+
else # else
|
69
|
+
add_to_set(field_name, actor.id) # self.add_to_set(:liker_ids, actor.id)
|
70
|
+
inc(counter_field_name.to_sym, 1) # inc(:likers_count, 1)
|
71
|
+
end # end
|
72
|
+
end # end
|
73
|
+
|
74
|
+
define_method "un#{passive_action}_by!" do |actor| # def unliked_by!(actor)
|
75
|
+
return false if actor.blank? # return false if actor.blank?
|
76
|
+
if actor.respond_to?("un#{action}!") # if actor.respond_to?(:unlike!)
|
77
|
+
actor.send("un#{action}!", self) # actor.unlike!(self)
|
78
|
+
else # else
|
79
|
+
pull(field_name, actor.id) # self.pull(:liker_ids, actor.id)
|
80
|
+
inc(counter_field_name.to_sym, -1) # inc(:likers_count, -1)
|
81
|
+
end # end
|
82
|
+
end # end
|
83
|
+
end
|
84
|
+
|
85
|
+
def doer(action, target, options = {})
|
86
|
+
|
87
|
+
action = action.to_s # "like"
|
88
|
+
base_action = (action[-1] == "e" ? action.chop : action) # "lik"
|
89
|
+
ing_action = base_action + "ing" # "liking"
|
90
|
+
passive_action = base_action + "ed" # "liked"
|
91
|
+
doer_action = base_action + "ers" # "likers"
|
92
|
+
|
93
|
+
field_name = "#{ing_action}_#{target.to_s.pluralize}_ids" # "liking_courses_ids"
|
94
|
+
target_field_name = "#{doer_action}_ids" # "likers_ids"
|
95
|
+
target_counter_name = "#{doer_action}_count" # "likers_count"
|
96
|
+
klass = (options[:class_name] || target.to_s.classify).constantize # Course
|
97
|
+
|
98
|
+
field field_name, type: Array, default: [], versioned: false # field :liking_courses_ids, type Array, default: [], versioned: false
|
99
|
+
|
100
|
+
define_method "#{ing_action}_#{target.to_s.pluralize}_count" do # def liking_courses_count
|
101
|
+
send(field_name).size # liking_courses_ids.size
|
102
|
+
end # end
|
103
|
+
|
104
|
+
unless options[:embedded]
|
105
|
+
define_method "#{ing_action}_#{target.to_s.pluralize}" do # def liking_courses
|
106
|
+
klass.where(:"_id".in => send(field_name)) # Course.where(:liking_courses_ids.in => liking_courses_ids)
|
107
|
+
end # end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
unless method_defined? "#{ing_action}?"
|
112
|
+
define_method "#{ing_action}?" do |model| # def liking?(course)
|
113
|
+
field = model.class.name.split(":").last.downcase #
|
114
|
+
send("#{ing_action}_#{field}?", model) # liking_course?(course)
|
115
|
+
end # end
|
116
|
+
end
|
117
|
+
|
118
|
+
define_method "#{ing_action}_#{target}?" do |model| # def liking_course?(course)
|
119
|
+
send(field_name).include?(model.id) # liking_courses_ids.include?(course.id)
|
120
|
+
end # end
|
121
|
+
|
122
|
+
unless method_defined? "#{action}!"
|
123
|
+
define_method "#{action}!" do |model| # def like!(couse)
|
124
|
+
field = model.class.name.split(":").last.downcase #
|
125
|
+
send("#{action}_#{field}!", model) # like_course!(course)
|
126
|
+
end # end
|
127
|
+
end
|
128
|
+
|
129
|
+
define_method "#{action}_#{target}!" do |model| # def like_course!(course)
|
130
|
+
return if send("#{ing_action}_#{target}?", model) # return if liking_course?(course)
|
131
|
+
|
132
|
+
model.add_to_set(target_field_name, self.id) if model.respond_to?(target_field_name) # course.add_to_set(:likers_ids, self.id) if model.respond_to?(:likers_ids)
|
133
|
+
model.inc(target_counter_name, 1) # coruse.inc(:likers_ids, 1)
|
134
|
+
add_to_set(field_name, model.id) # add_to_set(:liking_courses_ids, course.id)
|
135
|
+
end # end
|
136
|
+
|
137
|
+
|
138
|
+
unless method_defined? "un#{action}!"
|
139
|
+
define_method "un#{action}!" do |model| # def unlike!(course)
|
140
|
+
field = model.class.name.split(":").last.downcase #
|
141
|
+
send("un#{action}_#{field}!", model) # like_course!(course)
|
142
|
+
end # end
|
143
|
+
end
|
144
|
+
|
145
|
+
define_method "un#{action}_#{target}!" do |model| # def unlike_course!(course)
|
146
|
+
return unless send("#{ing_action}_#{target}?", model) # return unless liking_course?(course)
|
147
|
+
|
148
|
+
model.pull(target_field_name, self.id) if model.respond_to?(target_field_name) # course.pull(:likers_ids, self.id) if course.respond_to?(:likers_ids)
|
149
|
+
model.inc(target_counter_name, -1) # course.inc(likers_ids, -1)
|
150
|
+
self.pull(field_name, model.id) # self.pull(:liking_courses_ids)
|
151
|
+
end # end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
def doer_models # def doer_models
|
156
|
+
@doer_models ||= {} # @doer_models ||= {}
|
157
|
+
end # end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
@@ -0,0 +1,254 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Doable
|
4
|
+
class Course
|
5
|
+
end
|
6
|
+
class Student
|
7
|
+
end
|
8
|
+
|
9
|
+
class User
|
10
|
+
include Mongoid::Document
|
11
|
+
include Mongoid::Doable
|
12
|
+
|
13
|
+
doer :like, :course, class_name: "Doable::Course"
|
14
|
+
doer :like, :student, class_name: "Doable::Student", embedded: true
|
15
|
+
|
16
|
+
doable :follow, by: "Doable::User"
|
17
|
+
doer :follow, :user, class_name: "Doable::User"
|
18
|
+
|
19
|
+
doer :bookmark, :course, class_name: "Doable::Course"
|
20
|
+
end
|
21
|
+
|
22
|
+
class Course
|
23
|
+
include Mongoid::Document
|
24
|
+
include Mongoid::Doable
|
25
|
+
|
26
|
+
embeds_many :students
|
27
|
+
|
28
|
+
doable :like, by: "Doable::User"
|
29
|
+
doable :bookmark, by: "Doable::User"
|
30
|
+
end
|
31
|
+
|
32
|
+
class Student
|
33
|
+
include Mongoid::Document
|
34
|
+
include Mongoid::Doable
|
35
|
+
|
36
|
+
embedded_in :course
|
37
|
+
|
38
|
+
doable :like, by: "Doable::User"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "likeable" do
|
43
|
+
let(:user) { Doable::User.create }
|
44
|
+
let(:course) { Doable::Course.create }
|
45
|
+
|
46
|
+
subject { user }
|
47
|
+
|
48
|
+
context "default values" do
|
49
|
+
its(:liking_courses_ids) { should == [] }
|
50
|
+
its(:liking_courses_count) { should == 0 }
|
51
|
+
its(:liking_courses) { should == [] }
|
52
|
+
it { subject.should_not be_liking(course) }
|
53
|
+
|
54
|
+
context "with course" do
|
55
|
+
subject { course }
|
56
|
+
its(:likers_ids) { should == [] }
|
57
|
+
its(:likers_count) { should == 0 }
|
58
|
+
its(:likers) { should == [] }
|
59
|
+
it { subject.should_not be_liked_by(user) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when a user likes course" do
|
64
|
+
before { user.like!(course) }
|
65
|
+
|
66
|
+
its(:liking_courses_ids) { should == [course.id] }
|
67
|
+
its(:liking_courses_count) { should == 1 }
|
68
|
+
its(:liking_courses) { should == [course] }
|
69
|
+
it { subject.should be_liking(course) }
|
70
|
+
|
71
|
+
context "with course" do
|
72
|
+
subject { course }
|
73
|
+
its(:likers_ids) { should == [user.id] }
|
74
|
+
its(:likers_count) { should == 1 }
|
75
|
+
its(:likers) { should == [user]}
|
76
|
+
it { subject.should be_liked_by(user) }
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when the same user likes course once more" do
|
80
|
+
before { user.like!(course) }
|
81
|
+
|
82
|
+
its(:liking_courses_ids) { should == [course.id] }
|
83
|
+
its(:liking_courses_count) { should == 1 }
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when user unlike course" do
|
87
|
+
before { user.unlike!(course) }
|
88
|
+
|
89
|
+
its(:liking_courses_ids) { should == [] }
|
90
|
+
its(:liking_courses_count) { should == 0 }
|
91
|
+
its(:liking_courses) { should == [] }
|
92
|
+
it { subject.should_not be_liking(course) }
|
93
|
+
|
94
|
+
context "with course" do
|
95
|
+
subject { course }
|
96
|
+
its(:likers_ids) { should == [] }
|
97
|
+
its(:likers_count) { should == 0 }
|
98
|
+
its(:likers) { should == [] }
|
99
|
+
it { subject.should_not be_liked_by(user) }
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when user unlikes course" do
|
106
|
+
before { user.unlike!(course) }
|
107
|
+
|
108
|
+
its(:liking_courses_ids) { should == [] }
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
context "for embedded document" do
|
113
|
+
let(:student) { course.students.create }
|
114
|
+
subject { user }
|
115
|
+
|
116
|
+
its(:liking_students_count) { should == 0 }
|
117
|
+
it { subject.should_not be_respond_to(:liking_students) }
|
118
|
+
|
119
|
+
context "when a user likes student" do
|
120
|
+
before { user.like!(student) }
|
121
|
+
|
122
|
+
its(:liking_students_ids) { should == [student.id] }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
describe "followable" do
|
130
|
+
let(:user) { Doable::User.create }
|
131
|
+
let(:user2) { Doable::User.create }
|
132
|
+
|
133
|
+
subject { user }
|
134
|
+
|
135
|
+
context "default values" do
|
136
|
+
its(:following_users_ids) { should == [] }
|
137
|
+
its(:following_users_count) { should == 0 }
|
138
|
+
its(:following_users) { should == [] }
|
139
|
+
it { subject.should_not be_following(user2) }
|
140
|
+
its(:followers_ids) { should == [] }
|
141
|
+
its(:followers_count) { should == 0 }
|
142
|
+
its(:followers) { should == []}
|
143
|
+
it { subject.should_not be_followed_by(user2)}
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when user follows user2" do
|
147
|
+
before { user.follow!(user2) }
|
148
|
+
its(:following_users_ids) { should == [user2.id] }
|
149
|
+
its(:following_users_count) { should == 1 }
|
150
|
+
its(:following_users) { should == [user2] }
|
151
|
+
it { subject.should be_following(user2) }
|
152
|
+
its(:followers_ids) { should == [] }
|
153
|
+
its(:followers_count) { should == 0 }
|
154
|
+
its(:followers) { should == []}
|
155
|
+
it { subject.should_not be_followed_by(user2)}
|
156
|
+
|
157
|
+
context "with user2" do
|
158
|
+
subject { user2 }
|
159
|
+
its(:following_users_ids) { should == [] }
|
160
|
+
its(:following_users_count) { should == 0 }
|
161
|
+
its(:following_users) { should == [] }
|
162
|
+
it { subject.should_not be_following(user) }
|
163
|
+
its(:followers_ids) { should == [user.id] }
|
164
|
+
its(:followers_count) { should == 1 }
|
165
|
+
its(:followers) { should == [user]}
|
166
|
+
it { subject.should be_followed_by(user)}
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when user unfollows user2" do
|
170
|
+
before { user.unfollow!(user2) }
|
171
|
+
its(:following_users_ids) { should == [] }
|
172
|
+
its(:following_users_count) { should == 0 }
|
173
|
+
its(:following_users) { should == [] }
|
174
|
+
it { subject.should_not be_following(user2) }
|
175
|
+
its(:followers_ids) { should == [] }
|
176
|
+
its(:followers_count) { should == 0 }
|
177
|
+
its(:followers) { should == []}
|
178
|
+
it { subject.should_not be_followed_by(user2)}
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
describe "bookmarkable" do
|
186
|
+
let(:user) { Doable::User.create }
|
187
|
+
let(:course) { Doable::Course.create }
|
188
|
+
|
189
|
+
subject { user }
|
190
|
+
|
191
|
+
context "default values" do
|
192
|
+
its(:bookmarking_courses_ids) { should == [] }
|
193
|
+
its(:bookmarking_courses_count) { should == 0 }
|
194
|
+
its(:bookmarking_courses) { should == [] }
|
195
|
+
it { subject.should_not be_bookmarking(course) }
|
196
|
+
|
197
|
+
context "with course" do
|
198
|
+
subject { course }
|
199
|
+
its(:bookmarkers_ids) { should == [] }
|
200
|
+
its(:bookmarkers_count) { should == 0 }
|
201
|
+
its(:bookmarkers) { should == [] }
|
202
|
+
it { subject.should_not be_bookmarked_by(user) }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "when a user bookmarks course" do
|
207
|
+
before { user.bookmark_course!(course) }
|
208
|
+
|
209
|
+
its(:bookmarking_courses_ids) { should == [course.id] }
|
210
|
+
its(:bookmarking_courses_count) { should == 1 }
|
211
|
+
its(:bookmarking_courses) { should == [course] }
|
212
|
+
it { subject.should be_bookmarking(course) }
|
213
|
+
|
214
|
+
context "with course" do
|
215
|
+
subject { course }
|
216
|
+
its(:bookmarkers_ids) { should == [user.id] }
|
217
|
+
its(:bookmarkers_count) { should == 1 }
|
218
|
+
its(:bookmarkers) { should == [user] }
|
219
|
+
it { subject.should be_bookmarked_by(user) }
|
220
|
+
end
|
221
|
+
|
222
|
+
context "when the same user bookmarks course once more" do
|
223
|
+
before { user.bookmark_course!(course) }
|
224
|
+
|
225
|
+
its(:bookmarking_courses_ids) { should == [course.id] }
|
226
|
+
its(:bookmarking_courses_count) { should == 1 }
|
227
|
+
end
|
228
|
+
|
229
|
+
context "when user unbookmark course" do
|
230
|
+
before { user.unbookmark_course!(course) }
|
231
|
+
|
232
|
+
its(:bookmarking_courses_ids) { should == [] }
|
233
|
+
its(:bookmarking_courses_count) { should == 0 }
|
234
|
+
its(:bookmarking_courses) { should == [] }
|
235
|
+
it { subject.should_not be_bookmarking(course) }
|
236
|
+
|
237
|
+
context "with course" do
|
238
|
+
subject { course }
|
239
|
+
its(:bookmarkers_ids) { should == [] }
|
240
|
+
its(:bookmarkers_count) { should == 0 }
|
241
|
+
its(:bookmarkers) { should == [] }
|
242
|
+
it { subject.should_not be_bookmarked_by(user) }
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context "when user unbookmarks course" do
|
249
|
+
before { user.unbookmark_course!(course) }
|
250
|
+
|
251
|
+
its(:bookmarking_courses_ids) { should == [] }
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
require 'mongoid-doable'
|
9
|
+
require 'database_cleaner'
|
10
|
+
|
11
|
+
Mongoid.connect_to('doable_test')
|
12
|
+
|
13
|
+
# Requires supporting files with custom matchers and macros, etc,
|
14
|
+
# in ./support/ and its subdirectories.
|
15
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.before(:suite) do
|
19
|
+
DatabaseCleaner.strategy = :truncation
|
20
|
+
DatabaseCleaner.clean_with(:truncation)
|
21
|
+
end
|
22
|
+
|
23
|
+
config.before(:each) do
|
24
|
+
DatabaseCleaner.start
|
25
|
+
end
|
26
|
+
|
27
|
+
config.after(:each) do
|
28
|
+
DatabaseCleaner.clean
|
29
|
+
end
|
30
|
+
|
31
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
32
|
+
config.filter_run :focus => true
|
33
|
+
config.run_all_when_everything_filtered = true
|
34
|
+
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid-doable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- aproxacs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongoid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rdoc
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: jeweler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: database_cleaner
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: Able to do something like 'bookmark', 'like' or 'follow' with mongoid
|
127
|
+
email: aproxacs@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files:
|
131
|
+
- LICENSE.txt
|
132
|
+
- README.md
|
133
|
+
files:
|
134
|
+
- README.md
|
135
|
+
- Rakefile
|
136
|
+
- VERSION
|
137
|
+
- lib/mongoid-doable.rb
|
138
|
+
- lib/mongoid/doable.rb
|
139
|
+
- spec/mongoid/doable_spec.rb
|
140
|
+
- spec/spec_helper.rb
|
141
|
+
- LICENSE.txt
|
142
|
+
homepage: http://github.com/aproxacs/mongoid-doable
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ! '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
hash: 237706735236724821
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ! '>='
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
requirements: []
|
165
|
+
rubyforge_project:
|
166
|
+
rubygems_version: 1.8.24
|
167
|
+
signing_key:
|
168
|
+
specification_version: 3
|
169
|
+
summary: Able to do something like 'bookmark', 'like' or 'follow' with mongoid
|
170
|
+
test_files: []
|