resonance 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +159 -0
- data/Rakefile +7 -0
- data/lib/resonance.rb +94 -0
- data/lib/resonance/errors/argument_error.rb +5 -0
- data/lib/resonance/supports/converter.rb +42 -0
- data/lib/resonance/supports/patches.yml +3 -0
- data/lib/resonance/version.rb +3 -0
- data/resonance.gemspec +25 -0
- data/spec/dummy/application.rb +97 -0
- data/spec/dummy/bin/rails +5 -0
- data/spec/dummy/config.ru +1 -0
- data/spec/models/post_spec.rb +34 -0
- data/spec/models/user_spec.rb +106 -0
- data/spec/spec_helper.rb +1 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1706b436453caa501e2d7970f4eea6d0f39dd2a6
|
4
|
+
data.tar.gz: ef87ae52d6523a1f13fff3b917de503e95f0de71
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3727b7ef17bb964c388afc8ef8075aefa07f0cd63c14564def3e69161d8e07a5aabc8d62ee4d0dcfca7f184e36aaed2a5d9220f42e5d420ff02dd229f035a8e
|
7
|
+
data.tar.gz: f448efaf6e41d23c696761a8fcf6af51ea882025d56ae9ca4c82b1479b09a6622ebceb13d62f982a43c55607c8bd7d66e111e6352f6f362e5deeb358756a935d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015-2016 kami
|
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,159 @@
|
|
1
|
+
# Resonance
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/kami-zh/resonance.svg)](https://travis-ci.org/kami-zh/resonance)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/resonance.svg)](http://badge.fury.io/rb/resonance)
|
5
|
+
|
6
|
+
Resonance provides a relational feature to your Rails application, such as follow, like, and so on.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'resonance'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
```
|
19
|
+
$ bundle
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Resonance supports two way to add relational feature.
|
25
|
+
|
26
|
+
1. Add a feature to itself
|
27
|
+
2. Add features to two models
|
28
|
+
|
29
|
+
Following example shows about User model, however, you can apply to any models.
|
30
|
+
|
31
|
+
### 1. Add follow feature to User
|
32
|
+
|
33
|
+
This case adds follow feature to User model.
|
34
|
+
|
35
|
+
At first, generate User and Follow model:
|
36
|
+
|
37
|
+
```
|
38
|
+
$ bin/rails g model User
|
39
|
+
$ bin/rails g model Follow user_id:integer target_user_id:integer
|
40
|
+
```
|
41
|
+
|
42
|
+
And migrate:
|
43
|
+
|
44
|
+
```
|
45
|
+
$ bin/rake db:migrate
|
46
|
+
```
|
47
|
+
|
48
|
+
Then, define `Resonatable` module to `app/models/concerns/resonatable.rb`:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
module Resonatable
|
52
|
+
include Resonance
|
53
|
+
|
54
|
+
resonate :user, with: :user, by: :follow
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
At last, include this module from each models:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
class User < ActiveRecord::Base
|
62
|
+
include Resonatable
|
63
|
+
end
|
64
|
+
|
65
|
+
class Follow < ActiveRecord::Base
|
66
|
+
include Resonatable
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
That's it.
|
71
|
+
User instance has been added following methods:
|
72
|
+
|
73
|
+
- user.follow(other_user)
|
74
|
+
- user.unfollow(other_user)
|
75
|
+
- user.following?(other_user)
|
76
|
+
- user.following
|
77
|
+
- other_user.followed_by?(user)
|
78
|
+
- other_user.followers
|
79
|
+
|
80
|
+
Example:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
user = User.create
|
84
|
+
other_user = User.create
|
85
|
+
|
86
|
+
# Follow
|
87
|
+
user.follow other_user
|
88
|
+
user.following?(other_user) #=> true
|
89
|
+
user.following #=> <ActiveRecord::Associations::CollectionProxy [#<User id: 2, created_at: "2015-01-10 01:57:52", updated_at: "2015-01-10 01:57:52">]>
|
90
|
+
other_user.followed_by?(user) #=> true
|
91
|
+
other_user.followers #=> <ActiveRecord::Associations::CollectionProxy [#<User id: 1, created_at: "2015-01-10 01:57:42", updated_at: "2015-01-10 01:57:42">]>
|
92
|
+
|
93
|
+
# Unfollow
|
94
|
+
user.unfollow other_user
|
95
|
+
user.following?(other_user) #=> false
|
96
|
+
user.following #=> <ActiveRecord::Associations::CollectionProxy []>
|
97
|
+
other_user.followed_by?(user) #=> false
|
98
|
+
other_user.followers #=> <ActiveRecord::Associations::CollectionProxy []>
|
99
|
+
```
|
100
|
+
|
101
|
+
### 2. Add like feature to User and Post
|
102
|
+
|
103
|
+
This case adds like feature to User and Post model.
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
module Resonatable
|
107
|
+
include Resonance
|
108
|
+
|
109
|
+
resonate :user, with: :post, by: :like
|
110
|
+
end
|
111
|
+
|
112
|
+
class User < ActiveRecord::Base
|
113
|
+
include Resonatable
|
114
|
+
end
|
115
|
+
|
116
|
+
class Post < ActiveRecord::Base
|
117
|
+
include Resonatable
|
118
|
+
end
|
119
|
+
|
120
|
+
class Like < ActiveRecord::Base
|
121
|
+
include Resonatable
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
User and Post instance has been added following methods:
|
126
|
+
|
127
|
+
- user.like(post)
|
128
|
+
- user.unlike(post)
|
129
|
+
- user.liking?(post)
|
130
|
+
- user.liking
|
131
|
+
- post.liked_by?(user)
|
132
|
+
- post.likers
|
133
|
+
|
134
|
+
At the same time, some `resonate` methods are able to be defined:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
module Resonatable
|
138
|
+
include Resonance
|
139
|
+
|
140
|
+
resonate :user, with: :user, by: :follow
|
141
|
+
resonate :user, with: :post, by: :like
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
## Customization
|
146
|
+
|
147
|
+
If you want to use other foreign key name, you can define it by `:foreign_key` option.
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
resonate :user, with: :post, by: :like, foreign_key: :post_id # Default is `:target_post_id`
|
151
|
+
```
|
152
|
+
|
153
|
+
## Contributing
|
154
|
+
|
155
|
+
1. Fork it ( https://github.com/kami-zh/resonance/fork )
|
156
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
157
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
158
|
+
4. Push to the branch (git push origin my-new-feature)
|
159
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/resonance.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'resonance/errors/argument_error'
|
2
|
+
require 'resonance/supports/converter'
|
3
|
+
|
4
|
+
module Resonance
|
5
|
+
class << self
|
6
|
+
def included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
include Resonance::Supports::Converter
|
13
|
+
|
14
|
+
def resonate(subject, with: nil, by: nil, **options)
|
15
|
+
@roles = { source: subject, target: with, action: by }
|
16
|
+
@options = options
|
17
|
+
|
18
|
+
if @roles.values.any?(&:nil?)
|
19
|
+
raise Resonance::Errors::ArgumentError, 'Passed argument is not a valid'
|
20
|
+
end
|
21
|
+
|
22
|
+
classify(source).class_eval <<-EOS
|
23
|
+
has_many :#{pluralize(action)},
|
24
|
+
foreign_key: :#{source}_id,
|
25
|
+
dependent: :destroy
|
26
|
+
|
27
|
+
has_many :#{progressize(action)},
|
28
|
+
through: :#{pluralize(action)},
|
29
|
+
source: :target_#{target}
|
30
|
+
|
31
|
+
def #{action}(target)
|
32
|
+
if #{progressize(action)}?(target) || (self == target)
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
#{pluralize(action)}.create(#{foreign_key}: target.id)
|
37
|
+
end
|
38
|
+
|
39
|
+
def un#{action}(target)
|
40
|
+
unless #{progressize(action)}?(target)
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
#{pluralize(action)}.find_by(#{foreign_key}: target.id).destroy
|
45
|
+
end
|
46
|
+
|
47
|
+
def #{progressize(action)}?(target)
|
48
|
+
#{pluralize(action)}.exists?(#{foreign_key}: target.id)
|
49
|
+
end
|
50
|
+
EOS
|
51
|
+
|
52
|
+
classify(target).class_eval <<-EOS
|
53
|
+
has_many :#{pluralize(action)}_as_target,
|
54
|
+
foreign_key: :#{foreign_key},
|
55
|
+
class_name: '#{classify(action)}',
|
56
|
+
dependent: :destroy
|
57
|
+
|
58
|
+
has_many :#{peoplize(action)},
|
59
|
+
through: :#{pluralize(action)}_as_target,
|
60
|
+
source: :#{source}
|
61
|
+
|
62
|
+
def #{pastize(action)}_by?(source)
|
63
|
+
source.#{pluralize(action)}.exists?(#{foreign_key}: id)
|
64
|
+
end
|
65
|
+
EOS
|
66
|
+
|
67
|
+
classify(action).class_eval <<-EOS
|
68
|
+
belongs_to :#{source}
|
69
|
+
|
70
|
+
belongs_to :target_#{target},
|
71
|
+
class_name: '#{classify(target)}',
|
72
|
+
foreign_key: :#{foreign_key}
|
73
|
+
EOS
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def source
|
79
|
+
@roles[:source].to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
def target
|
83
|
+
@roles[:target].to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def action
|
87
|
+
@roles[:action].to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def foreign_key
|
91
|
+
@options[:foreign_key] || "target_#{target}_id"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'verbs'
|
2
|
+
|
3
|
+
module Resonance
|
4
|
+
module Supports
|
5
|
+
module Converter
|
6
|
+
private
|
7
|
+
|
8
|
+
def classify(str)
|
9
|
+
str.capitalize.constantize
|
10
|
+
end
|
11
|
+
|
12
|
+
def pluralize(str)
|
13
|
+
str.pluralize
|
14
|
+
end
|
15
|
+
|
16
|
+
def progressize(str)
|
17
|
+
if patches['progressize'].key?(str)
|
18
|
+
return patches['progressize'][str]
|
19
|
+
end
|
20
|
+
|
21
|
+
str.verb.conjugate(aspect: :progressive).split(' ').last
|
22
|
+
end
|
23
|
+
|
24
|
+
def peoplize(str)
|
25
|
+
str = (str.last == 'e') ? str.chop : str
|
26
|
+
str + 'ers'
|
27
|
+
end
|
28
|
+
|
29
|
+
def pastize(str)
|
30
|
+
str.verb.conjugate(tense: :past).split(' ').last
|
31
|
+
end
|
32
|
+
|
33
|
+
def patches
|
34
|
+
@patches ||= YAML.load_file(patches_path)['patches']
|
35
|
+
end
|
36
|
+
|
37
|
+
def patches_path
|
38
|
+
File.expand_path('../patches.yml', __FILE__)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/resonance.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'resonance/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'resonance'
|
7
|
+
s.version = Resonance::VERSION
|
8
|
+
s.authors = 'kami'
|
9
|
+
s.email = 'hiroki.zenigami@gmail.com'
|
10
|
+
|
11
|
+
s.summary = 'Provides a relational feature to your Rails application.'
|
12
|
+
s.description = 'Provides a relational feature to your Rails application.'
|
13
|
+
s.homepage = 'https://github.com/kami-zh/resonance'
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.files = `git ls-files -z`.split("\x0")
|
17
|
+
|
18
|
+
s.add_dependency 'activesupport'
|
19
|
+
s.add_dependency 'verbs'
|
20
|
+
|
21
|
+
s.add_development_dependency 'rspec-rails'
|
22
|
+
s.add_development_dependency 'actionpack'
|
23
|
+
s.add_development_dependency 'activerecord'
|
24
|
+
s.add_development_dependency 'sqlite3'
|
25
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
$:.unshift File.expand_path('../../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'action_controller/railtie'
|
4
|
+
require 'active_record'
|
5
|
+
require 'resonance'
|
6
|
+
|
7
|
+
module Dummy
|
8
|
+
class Application < Rails::Application
|
9
|
+
config.secret_token = 'abcdefghijklmnopqrstuvwxyz0123456789'
|
10
|
+
config.session_store :cookie_store, key: '_dummy_session'
|
11
|
+
config.eager_load = false
|
12
|
+
config.active_support.deprecation = :log
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Dummy::Application.initialize!
|
17
|
+
|
18
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
19
|
+
|
20
|
+
#
|
21
|
+
# Models
|
22
|
+
#
|
23
|
+
|
24
|
+
class User < ActiveRecord::Base; end
|
25
|
+
class Post < ActiveRecord::Base; end
|
26
|
+
class Follow < ActiveRecord::Base; end
|
27
|
+
class Like < ActiveRecord::Base; end
|
28
|
+
|
29
|
+
module Resonatable
|
30
|
+
include Resonance
|
31
|
+
|
32
|
+
resonate :user, with: :user, by: :follow
|
33
|
+
resonate :user, with: :post, by: :like, foreign_key: :post_id
|
34
|
+
end
|
35
|
+
|
36
|
+
class User
|
37
|
+
include Resonatable
|
38
|
+
end
|
39
|
+
|
40
|
+
class Post
|
41
|
+
include Resonatable
|
42
|
+
end
|
43
|
+
|
44
|
+
class Follow
|
45
|
+
include Resonatable
|
46
|
+
end
|
47
|
+
|
48
|
+
class Like
|
49
|
+
include Resonatable
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Migrates
|
54
|
+
#
|
55
|
+
|
56
|
+
class CreateUsers < ActiveRecord::Migration
|
57
|
+
def change
|
58
|
+
create_table :users do |t|
|
59
|
+
t.timestamps null: false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class CreatePosts < ActiveRecord::Migration
|
65
|
+
def change
|
66
|
+
create_table :posts do |t|
|
67
|
+
t.timestamps null: false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class CreateFollows < ActiveRecord::Migration
|
73
|
+
def change
|
74
|
+
create_table :follows do |t|
|
75
|
+
t.integer :user_id
|
76
|
+
t.integer :target_user_id
|
77
|
+
|
78
|
+
t.timestamps null: false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class CreateLikes < ActiveRecord::Migration
|
84
|
+
def change
|
85
|
+
create_table :likes do |t|
|
86
|
+
t.integer :user_id
|
87
|
+
t.integer :post_id
|
88
|
+
|
89
|
+
t.timestamps null: false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
CreateUsers.new.change
|
95
|
+
CreatePosts.new.change
|
96
|
+
CreateFollows.new.change
|
97
|
+
CreateLikes.new.change
|
@@ -0,0 +1 @@
|
|
1
|
+
run Rails.application
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Post, type: :model do
|
4
|
+
let(:user) { User.create }
|
5
|
+
let(:post) { Post.create }
|
6
|
+
|
7
|
+
describe 'instance methods' do
|
8
|
+
it 'should be defined' do
|
9
|
+
# :user resonates with :post by :like
|
10
|
+
expect(post).not_to respond_to(:like)
|
11
|
+
expect(post).not_to respond_to(:unlike)
|
12
|
+
expect(post).not_to respond_to(:liking?)
|
13
|
+
expect(post).not_to respond_to(:liking)
|
14
|
+
expect(post).to respond_to(:liked_by?)
|
15
|
+
expect(post).to respond_to(:likers)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#liked_by?' do
|
20
|
+
before { user.like post }
|
21
|
+
|
22
|
+
it 'should be liked by user' do
|
23
|
+
expect(post).to be_liked_by(user)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#likers' do
|
28
|
+
before { user.like post }
|
29
|
+
|
30
|
+
it 'should be included user' do
|
31
|
+
expect(post.likers).to be_exists(id: user.id)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe User, type: :model do
|
4
|
+
let(:user) { User.create }
|
5
|
+
let(:other_user) { User.create }
|
6
|
+
|
7
|
+
describe 'instance methods' do
|
8
|
+
it 'should be defined' do
|
9
|
+
# :user resonates with :user by :follow
|
10
|
+
expect(user).to respond_to(:follow)
|
11
|
+
expect(user).to respond_to(:unfollow)
|
12
|
+
expect(user).to respond_to(:following?)
|
13
|
+
expect(user).to respond_to(:following)
|
14
|
+
expect(user).to respond_to(:followed_by?)
|
15
|
+
expect(user).to respond_to(:followers)
|
16
|
+
|
17
|
+
# :user resonates with :post by :like
|
18
|
+
expect(user).to respond_to(:like)
|
19
|
+
expect(user).to respond_to(:unlike)
|
20
|
+
expect(user).to respond_to(:liking?)
|
21
|
+
expect(user).to respond_to(:liking)
|
22
|
+
expect(user).not_to respond_to(:liked_by?)
|
23
|
+
expect(user).not_to respond_to(:likers)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#follow' do
|
28
|
+
context 'unfollow user' do
|
29
|
+
before { user.follow other_user }
|
30
|
+
|
31
|
+
it 'should be followed' do
|
32
|
+
expect(user.follows).to be_exists(target_user_id: other_user.id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'following user' do
|
37
|
+
before do
|
38
|
+
user.follow other_user
|
39
|
+
user.follow other_user
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should be followed only once' do
|
43
|
+
expect(user.follows.count).to eq(1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'user-self' do
|
48
|
+
before { user.follow user }
|
49
|
+
|
50
|
+
it 'should not be followed' do
|
51
|
+
expect(user.follows).not_to be_exists(target_user_id: user.id)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#unfollow' do
|
57
|
+
context 'following user' do
|
58
|
+
before do
|
59
|
+
user.follow other_user
|
60
|
+
user.unfollow other_user
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should be unfollowed' do
|
64
|
+
expect(user.follows).not_to be_exists(target_user_id: other_user.id)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'unfollow user' do
|
69
|
+
it 'should not raise error' do
|
70
|
+
expect { user.unfollow other_user }.not_to raise_error
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#following?' do
|
76
|
+
before { user.follow other_user }
|
77
|
+
|
78
|
+
it 'should be followed' do
|
79
|
+
expect(user).to be_following(other_user)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#following' do
|
84
|
+
before { user.follow other_user }
|
85
|
+
|
86
|
+
it 'should be included other user' do
|
87
|
+
expect(user.following).to be_exists(other_user.id)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#followed_by?' do
|
92
|
+
before { other_user.follow user }
|
93
|
+
|
94
|
+
it 'should be followed by other user' do
|
95
|
+
expect(user).to be_followed_by(other_user)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#followers' do
|
100
|
+
before { other_user.follow user }
|
101
|
+
|
102
|
+
it 'should be included other user' do
|
103
|
+
expect(user.followers).to be_exists(other_user.id)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'dummy/application'
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resonance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kami
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: verbs
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: actionpack
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Provides a relational feature to your Rails application.
|
98
|
+
email: hiroki.zenigami@gmail.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- ".gitignore"
|
104
|
+
- ".travis.yml"
|
105
|
+
- Gemfile
|
106
|
+
- MIT-LICENSE
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- lib/resonance.rb
|
110
|
+
- lib/resonance/errors/argument_error.rb
|
111
|
+
- lib/resonance/supports/converter.rb
|
112
|
+
- lib/resonance/supports/patches.yml
|
113
|
+
- lib/resonance/version.rb
|
114
|
+
- resonance.gemspec
|
115
|
+
- spec/dummy/application.rb
|
116
|
+
- spec/dummy/bin/rails
|
117
|
+
- spec/dummy/config.ru
|
118
|
+
- spec/models/post_spec.rb
|
119
|
+
- spec/models/user_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
homepage: https://github.com/kami-zh/resonance
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 2.5.1
|
142
|
+
signing_key:
|
143
|
+
specification_version: 4
|
144
|
+
summary: Provides a relational feature to your Rails application.
|
145
|
+
test_files: []
|