resonance 0.3.2

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.
@@ -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
@@ -0,0 +1,6 @@
1
+ .bundle/
2
+ pkg/
3
+ spec/dummy/db
4
+ spec/dummy/log
5
+ spec/dummy/tmp/
6
+ Gemfile.lock
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -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.
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ task default: :spec
@@ -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,5 @@
1
+ module Resonance
2
+ module Errors
3
+ class ArgumentError < StandardError; end
4
+ end
5
+ 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
@@ -0,0 +1,3 @@
1
+ patches:
2
+ progressize:
3
+ follow: following
@@ -0,0 +1,3 @@
1
+ module Resonance
2
+ VERSION = '0.3.2'
3
+ end
@@ -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,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ APP_PATH = File.expand_path('../../application', __FILE__)
4
+
5
+ require 'rails/commands'
@@ -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
@@ -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: []